451973 - Ambiguous module init location when mixing --add-to-start & --add-to-startd in the same exec
+ Cleaning up entire base buildout into BaseBuilder class + The management of the configuration is maintained in - StartDirBuilder - StartIniBuilder + The buildout of the directories from the [files] section is now maintained by the BaseBuilder itself. + Using new FileInitializer system as well + Using new Licensing system as well
This commit is contained in:
parent
61e480c2c1
commit
dbf6f2e644
|
@ -0,0 +1,365 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.start;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.start.Modules.AndMatcher;
|
||||
import org.eclipse.jetty.start.Modules.EnabledMatcher;
|
||||
import org.eclipse.jetty.start.Modules.Matcher;
|
||||
import org.eclipse.jetty.start.Modules.SourceSetMatcher;
|
||||
import org.eclipse.jetty.start.Modules.UniqueSourceMatcher;
|
||||
import org.eclipse.jetty.start.builders.StartDirBuilder;
|
||||
import org.eclipse.jetty.start.builders.StartIniBuilder;
|
||||
import org.eclipse.jetty.start.fileinits.MavenLocalRepoFileInitializer;
|
||||
import org.eclipse.jetty.start.fileinits.TestFileInitializer;
|
||||
import org.eclipse.jetty.start.fileinits.UriFileInitializer;
|
||||
|
||||
/**
|
||||
* Build a start configuration in <code>${jetty.base}</code>, including
|
||||
* ini files, directories, and libs. Also handles License management.
|
||||
*/
|
||||
public class BaseBuilder
|
||||
{
|
||||
public static interface Config
|
||||
{
|
||||
/**
|
||||
* Add a module to the start environment in <code>${jetty.base}</code>
|
||||
*
|
||||
* @param module
|
||||
* the module to add
|
||||
* @return true if module was added, false if module was not added
|
||||
* (because that module already exists)
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean addModule(Module module) throws IOException;
|
||||
}
|
||||
|
||||
private static final String EXITING_LICENSE_NOT_ACKNOWLEDGED = "Exiting: license not acknowledged!";
|
||||
|
||||
private final BaseHome baseHome;
|
||||
private final List<FileInitializer> fileInitializers;
|
||||
private final StartArgs startArgs;
|
||||
|
||||
public BaseBuilder(BaseHome baseHome, StartArgs args)
|
||||
{
|
||||
this.baseHome = baseHome;
|
||||
this.startArgs = args;
|
||||
this.fileInitializers = new ArrayList<>();
|
||||
|
||||
// Establish FileInitializers
|
||||
if (args.isTestingModeEnabled())
|
||||
{
|
||||
// No downloads performed
|
||||
fileInitializers.add(new TestFileInitializer());
|
||||
}
|
||||
else if (args.isDownload())
|
||||
{
|
||||
// Downloads are allowed to be performed
|
||||
// Setup Maven Local Repo
|
||||
Path localRepoDir = args.getMavenLocalRepoDir();
|
||||
if (localRepoDir != null)
|
||||
{
|
||||
// Use provided local repo directory
|
||||
fileInitializers.add(new MavenLocalRepoFileInitializer(baseHome,localRepoDir));
|
||||
}
|
||||
else
|
||||
{
|
||||
// No no local repo directory (direct downloads)
|
||||
fileInitializers.add(new MavenLocalRepoFileInitializer(baseHome));
|
||||
}
|
||||
|
||||
// Normal URL downloads
|
||||
fileInitializers.add(new UriFileInitializer(baseHome));
|
||||
}
|
||||
}
|
||||
|
||||
private void ackLicenses() throws IOException
|
||||
{
|
||||
if (startArgs.isLicenseCheckRequired())
|
||||
{
|
||||
if (startArgs.isApproveAllLicenses())
|
||||
{
|
||||
StartLog.info("All Licenses Approved via Command Line Option");
|
||||
}
|
||||
else
|
||||
{
|
||||
Licensing licensing = new Licensing();
|
||||
for (Module module : startArgs.getAllModules().getEnabled())
|
||||
{
|
||||
licensing.addModule(module);
|
||||
}
|
||||
|
||||
if (licensing.hasLicenses())
|
||||
{
|
||||
StartLog.debug("Requesting License Acknowledgement");
|
||||
if (!licensing.acknowledgeLicenses())
|
||||
{
|
||||
StartLog.warn(EXITING_LICENSE_NOT_ACKNOWLEDGED);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build out the Base directory (if needed)
|
||||
*
|
||||
* @return true if base directory was changed, false if left unchanged.
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean build() throws IOException
|
||||
{
|
||||
Modules modules = startArgs.getAllModules();
|
||||
boolean dirty = false;
|
||||
|
||||
String dirSource = "<add-to-startd>";
|
||||
String iniSource = "<add-to-start-ini>";
|
||||
|
||||
int count = 0;
|
||||
count += modules.enableAll(startArgs.getAddToStartdIni(),dirSource);
|
||||
count += modules.enableAll(startArgs.getAddToStartIni(),iniSource);
|
||||
|
||||
Matcher startDMatcher = new AndMatcher(new EnabledMatcher(),new UniqueSourceMatcher(dirSource));
|
||||
Matcher startIniMatcher = new AndMatcher(new EnabledMatcher(),new UniqueSourceMatcher(iniSource));
|
||||
|
||||
// look for ambiguous declaration in 2 places
|
||||
Matcher ambiguousMatcher = new AndMatcher(new EnabledMatcher(),new SourceSetMatcher(dirSource,iniSource));
|
||||
List<Module> ambiguous = modules.getMatching(ambiguousMatcher);
|
||||
|
||||
if (ambiguous.size() > 0)
|
||||
{
|
||||
StringBuilder err = new StringBuilder();
|
||||
err.append("Unable to add ");
|
||||
err.append(ambiguous.size());
|
||||
err.append(" module");
|
||||
if (ambiguous.size() > 1)
|
||||
{
|
||||
err.append('s');
|
||||
}
|
||||
err.append(" (found declared via both --add-to-start and --add-to-startd): [");
|
||||
for (int i = 0; i < ambiguous.size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
err.append(", ");
|
||||
}
|
||||
err.append(ambiguous.get(i).getName());
|
||||
}
|
||||
err.append(']');
|
||||
throw new RuntimeException(err.toString());
|
||||
}
|
||||
|
||||
StartLog.debug("Adding %s new module(s)",count);
|
||||
|
||||
// Acknowledge Licenses
|
||||
ackLicenses();
|
||||
|
||||
// Collect specific modules to enable
|
||||
List<Module> startDModules = modules.getMatching(startDMatcher);
|
||||
List<Module> startIniModules = modules.getMatching(startIniMatcher);
|
||||
|
||||
List<FileArg> files = new ArrayList<FileArg>();
|
||||
|
||||
if (!startDModules.isEmpty())
|
||||
{
|
||||
StartDirBuilder builder = new StartDirBuilder(this);
|
||||
for (Module mod : startDModules)
|
||||
{
|
||||
dirty |= builder.addModule(mod);
|
||||
for (String file : mod.getFiles())
|
||||
{
|
||||
files.add(new FileArg(mod,file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!startIniModules.isEmpty())
|
||||
{
|
||||
StartIniBuilder builder = new StartIniBuilder(this);
|
||||
for (Module mod : startIniModules)
|
||||
{
|
||||
dirty |= builder.addModule(mod);
|
||||
for (String file : mod.getFiles())
|
||||
{
|
||||
files.add(new FileArg(mod,file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process files
|
||||
files.addAll(startArgs.getFiles());
|
||||
dirty |= processFileResources(files);
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
public BaseHome getBaseHome()
|
||||
{
|
||||
return baseHome;
|
||||
}
|
||||
|
||||
public StartArgs getStartArgs()
|
||||
{
|
||||
return startArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a specific file resource
|
||||
*
|
||||
* @param arg
|
||||
* the fileArg to work with
|
||||
* @param file
|
||||
* the resolved file reference to work with
|
||||
* @return true if change was made as a result of the file, false if no change made.
|
||||
* @throws IOException
|
||||
* if there was an issue in processing this file
|
||||
*/
|
||||
private boolean processFileResource(FileArg arg, Path file) throws IOException
|
||||
{
|
||||
if (startArgs.isDownload() && (arg.uri != null))
|
||||
{
|
||||
URI uri = URI.create(arg.uri);
|
||||
|
||||
// Process via initializers
|
||||
for (FileInitializer finit : fileInitializers)
|
||||
{
|
||||
if (finit.init(uri,file))
|
||||
{
|
||||
// Completed successfully
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Process directly
|
||||
boolean isDir = arg.location.endsWith("/");
|
||||
|
||||
if (FS.exists(file))
|
||||
{
|
||||
// Validate existence
|
||||
if (isDir)
|
||||
{
|
||||
if (!Files.isDirectory(file))
|
||||
{
|
||||
throw new IOException("Invalid: path should be a directory (but isn't): " + file);
|
||||
}
|
||||
if (!FS.canReadDirectory(file))
|
||||
{
|
||||
throw new IOException("Unable to read directory: " + file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!FS.canReadFile(file))
|
||||
{
|
||||
throw new IOException("Unable to read file: " + file);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isDir)
|
||||
{
|
||||
// Create directory
|
||||
StartLog.log("MKDIR",baseHome.toShortForm(file));
|
||||
return FS.ensureDirectoryExists(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Warn on missing file (this has to be resolved manually by user)
|
||||
String shortRef = baseHome.toShortForm(file);
|
||||
if (startArgs.isTestingModeEnabled())
|
||||
{
|
||||
StartLog.log("TESTING MODE","Skipping required file check on: %s",shortRef);
|
||||
return true;
|
||||
}
|
||||
|
||||
StartLog.warn("Missing Required File: %s",baseHome.toShortForm(file));
|
||||
startArgs.setRun(false);
|
||||
if (arg.uri != null)
|
||||
{
|
||||
StartLog.warn(" Can be downloaded From: %s",arg.uri);
|
||||
StartLog.warn(" Run start.jar --create-files to download");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the {@link FileArg} for startup, assume that all licenses have
|
||||
* been acknowledged at this stage.
|
||||
*
|
||||
* @param files
|
||||
* the list of {@link FileArg}s to process
|
||||
* @return true if base directory modified, false if left untouched
|
||||
*/
|
||||
private boolean processFileResources(List<FileArg> files) throws IOException
|
||||
{
|
||||
if ((files == null) || (files.isEmpty()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean dirty = false;
|
||||
|
||||
List<String> failures = new ArrayList<String>();
|
||||
|
||||
for (FileArg arg : files)
|
||||
{
|
||||
Path file = baseHome.getBasePath(arg.location);
|
||||
try
|
||||
{
|
||||
dirty |= processFileResource(arg,file);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
StartLog.warn(t);
|
||||
failures.add(String.format("[%s] %s - %s",t.getClass().getSimpleName(),t.getMessage(),file.toAbsolutePath().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!failures.isEmpty())
|
||||
{
|
||||
StringBuilder err = new StringBuilder();
|
||||
err.append("Failed to process all file resources.");
|
||||
for (String failure : failures)
|
||||
{
|
||||
err.append(System.lineSeparator()).append(" - ").append(failure);
|
||||
}
|
||||
StartLog.warn(err.toString());
|
||||
|
||||
throw new RuntimeException(err.toString());
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
}
|
|
@ -67,14 +67,15 @@ public class FS
|
|||
return Files.exists(ret);
|
||||
}
|
||||
|
||||
public static void ensureDirectoryExists(Path dir) throws IOException
|
||||
public static boolean ensureDirectoryExists(Path dir) throws IOException
|
||||
{
|
||||
if (exists(dir))
|
||||
{
|
||||
// exists already, nothing to do
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
Files.createDirectories(dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void ensureDirectoryWritable(Path dir) throws IOException
|
||||
|
|
|
@ -34,8 +34,8 @@ public interface FileInitializer
|
|||
* the remote URI of the resource acting as its source
|
||||
* @param file
|
||||
* the local file resource to initialize
|
||||
* @return true if local file is initialized, false if this
|
||||
* {@link FileInitializer} skipped this attempt.
|
||||
* @return true if local file is initialized (resulted in a change on disk), false if this
|
||||
* {@link FileInitializer} did nothing.
|
||||
* @throws IOException
|
||||
* if there was an attempt to initialize, but an error occurred.
|
||||
*/
|
||||
|
|
|
@ -21,37 +21,23 @@ package org.eclipse.jetty.start;
|
|||
import static org.eclipse.jetty.start.UsageException.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.start.config.CommandLineConfigSource;
|
||||
import org.eclipse.jetty.start.fileinits.MavenLocalRepoFileInitializer;
|
||||
import org.eclipse.jetty.start.fileinits.TestFileInitializer;
|
||||
import org.eclipse.jetty.start.fileinits.UriFileInitializer;
|
||||
|
||||
/**
|
||||
* Main start class.
|
||||
|
@ -82,7 +68,6 @@ import org.eclipse.jetty.start.fileinits.UriFileInitializer;
|
|||
*/
|
||||
public class Main
|
||||
{
|
||||
private static final String EXITING_LICENSE_NOT_ACKNOWLEDGED = "Exiting: license not acknowledged!";
|
||||
private static final int EXIT_USAGE = 1;
|
||||
|
||||
public static void main(String[] args)
|
||||
|
@ -272,222 +257,6 @@ public class Main
|
|||
modules.dumpEnabledTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build out INI file.
|
||||
* <p>
|
||||
* This applies equally for either <code>${jetty.base}/start.ini</code> or
|
||||
* <code>${jetty.base}/start.d/${name}.ini</code>
|
||||
*
|
||||
* @param fileInitializers the configured initializers
|
||||
* @param args the arguments of what modules are enabled
|
||||
* @param name the name of the module to based the build of the ini
|
||||
* @param topLevel
|
||||
* @param appendStartIni true to append to <code>${jetty.base}/start.ini</code>,
|
||||
* false to create a <code>${jetty.base}/start.d/${name}.ini</code> entry instead.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void buildIni(List<FileInitializer> fileInitializers, StartArgs args, String name, boolean topLevel, boolean appendStartIni) throws IOException
|
||||
{
|
||||
// Find the start.d relative to the base directory only.
|
||||
Path start_d = baseHome.getBasePath("start.d");
|
||||
|
||||
// Is this a module?
|
||||
Modules modules = args.getAllModules();
|
||||
Module module = modules.get(name);
|
||||
if (module == null)
|
||||
{
|
||||
StartLog.warn("ERROR: No known module for %s",name);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean transitive = module.isEnabled() && (module.getSources().size() == 0);
|
||||
|
||||
// Find any named ini file and check it follows the convention
|
||||
Path start_ini = baseHome.getBasePath("start.ini");
|
||||
String short_start_ini = baseHome.toShortForm(start_ini);
|
||||
Path startd_ini = start_d.resolve(name + ".ini");
|
||||
String short_startd_ini = baseHome.toShortForm(startd_ini);
|
||||
StartIni module_ini = null;
|
||||
if (FS.exists(startd_ini))
|
||||
{
|
||||
module_ini = new StartIni(startd_ini);
|
||||
if (module_ini.getLineMatches(Pattern.compile("--module=(.*, *)*" + name)).size() == 0)
|
||||
{
|
||||
StartLog.warn("ERROR: %s is not enabled in %s!",name,short_startd_ini);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!args.isApproveAllLicenses())
|
||||
{
|
||||
if (!module.acknowledgeLicense())
|
||||
{
|
||||
StartLog.warn(EXITING_LICENSE_NOT_ACKNOWLEDGED);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
boolean buildIni=false;
|
||||
if (module.isEnabled())
|
||||
{
|
||||
// is it an explicit request to create an ini file?
|
||||
if (topLevel && !FS.exists(startd_ini) && !appendStartIni)
|
||||
{
|
||||
buildIni=true;
|
||||
}
|
||||
// else is it transitive
|
||||
else if (transitive)
|
||||
{
|
||||
if (module.hasDefaultConfig())
|
||||
{
|
||||
buildIni = true;
|
||||
StartLog.info("%-15s initialised transitively",name);
|
||||
}
|
||||
}
|
||||
// else must be initialized explicitly
|
||||
else
|
||||
{
|
||||
for (String source : module.getSources())
|
||||
{
|
||||
StartLog.info("%-15s initialised in %s",name,baseHome.toShortForm(source));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buildIni=true;
|
||||
}
|
||||
|
||||
String source = "<transitive>";
|
||||
|
||||
// If we need an ini
|
||||
if (buildIni)
|
||||
{
|
||||
// File BufferedWriter
|
||||
BufferedWriter writer = null;
|
||||
PrintWriter out = null;
|
||||
try
|
||||
{
|
||||
if (appendStartIni)
|
||||
{
|
||||
source = short_start_ini;
|
||||
StartLog.info("%-15s initialised in %s (appended)",name,source);
|
||||
writer = Files.newBufferedWriter(start_ini,StandardCharsets.UTF_8,StandardOpenOption.CREATE,StandardOpenOption.APPEND);
|
||||
out = new PrintWriter(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the directory if needed
|
||||
FS.ensureDirectoryExists(start_d);
|
||||
FS.ensureDirectoryWritable(start_d);
|
||||
source = short_startd_ini;
|
||||
StartLog.info("%-15s initialised in %s (created)",name,source);
|
||||
writer = Files.newBufferedWriter(startd_ini,StandardCharsets.UTF_8,StandardOpenOption.CREATE_NEW,StandardOpenOption.WRITE);
|
||||
out = new PrintWriter(writer);
|
||||
}
|
||||
|
||||
if (appendStartIni)
|
||||
{
|
||||
out.println();
|
||||
}
|
||||
out.println("# --------------------------------------- ");
|
||||
out.println("# Module: " + name);
|
||||
|
||||
out.println("--module=" + name);
|
||||
|
||||
args.parse("--module=" + name,source);
|
||||
args.parseModule(module);
|
||||
|
||||
for (String line : module.getDefaultConfig())
|
||||
{
|
||||
out.println(line);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (out != null)
|
||||
{
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modules.enable(name,Collections.singletonList(source));
|
||||
|
||||
// Also list other places this module is enabled
|
||||
for (String src : module.getSources())
|
||||
{
|
||||
StartLog.debug("also enabled in: %s",src);
|
||||
if (!short_start_ini.equals(src))
|
||||
{
|
||||
StartLog.info("%-15s enabled in %s",name,baseHome.toShortForm(src));
|
||||
}
|
||||
}
|
||||
|
||||
// Do downloads now
|
||||
List<FileArg> files = new ArrayList<FileArg>();
|
||||
for (String file : module.getFiles())
|
||||
{
|
||||
files.add(new FileArg(module,file));
|
||||
}
|
||||
processFileResources(fileInitializers,args,files);
|
||||
|
||||
// Process dependencies
|
||||
module.expandProperties(args.getProperties());
|
||||
modules.registerParentsIfMissing(module);
|
||||
modules.buildGraph();
|
||||
|
||||
// process new ini modules
|
||||
if (topLevel)
|
||||
{
|
||||
List<Module> depends = new ArrayList<>();
|
||||
for (String depend : modules.resolveParentModulesOf(name))
|
||||
{
|
||||
if (!name.equals(depend))
|
||||
{
|
||||
Module m = modules.get(depend);
|
||||
m.setEnabled(true);
|
||||
depends.add(m);
|
||||
}
|
||||
}
|
||||
Collections.sort(depends,Collections.reverseOrder(new Module.DepthComparator()));
|
||||
|
||||
Set<String> done = new HashSet<>(0);
|
||||
while (true)
|
||||
{
|
||||
// initialize known dependencies
|
||||
boolean complete=true;
|
||||
for (Module m : depends)
|
||||
{
|
||||
if (!done.contains(m.getName()))
|
||||
{
|
||||
complete=false;
|
||||
buildIni(fileInitializers,args,m.getName(),false,appendStartIni);
|
||||
done.add(m.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (complete)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// look for any new ones resolved via expansion
|
||||
depends.clear();
|
||||
for (String depend : modules.resolveParentModulesOf(name))
|
||||
{
|
||||
if (!name.equals(depend))
|
||||
{
|
||||
Module m = modules.get(depend);
|
||||
m.setEnabled(true);
|
||||
depends.add(m);
|
||||
}
|
||||
}
|
||||
Collections.sort(depends,Collections.reverseOrder(new Module.DepthComparator()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience for <code>processCommandLine(cmdLine.toArray(new String[cmdLine.size()]))</code>
|
||||
*/
|
||||
|
@ -534,7 +303,8 @@ public class Main
|
|||
modules.buildGraph();
|
||||
|
||||
args.setAllModules(modules);
|
||||
List<Module> activeModules = modules.resolveEnabled();
|
||||
List<Module> activeModules = modules.getEnabled();
|
||||
modules.assertModulesValid(activeModules);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 5) Lib & XML Expansion / Resolution
|
||||
|
@ -552,139 +322,6 @@ public class Main
|
|||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the {@link FileArg} for startup, assume that all licenses have
|
||||
* been acknowledged at this stage.
|
||||
*
|
||||
* @param fileInitializers the file initializer mechanisms.
|
||||
* @param args the start arguments
|
||||
*/
|
||||
private void processFileResources(List<FileInitializer> fileInitializers, StartArgs args) throws IOException
|
||||
{
|
||||
processFileResources(fileInitializers,args,args.getFiles());
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the {@link FileArg} for startup, assume that all licenses have
|
||||
* been acknowledged at this stage.
|
||||
*
|
||||
* @param fileInitializers the file initializer mechanisms.
|
||||
* @param args the start arguments
|
||||
* @param files the list of {@link FileArg}s to process
|
||||
*/
|
||||
private void processFileResources(List<FileInitializer> fileInitializers, StartArgs args, List<FileArg> files) throws IOException
|
||||
{
|
||||
List<String> failures = new ArrayList<String>();
|
||||
|
||||
for (FileArg arg : files)
|
||||
{
|
||||
Path file = baseHome.getBasePath(arg.location);
|
||||
try
|
||||
{
|
||||
if (!processFileResource(fileInitializers,args,arg,file))
|
||||
{
|
||||
failures.add(String.format("[GenericError] %s",file.toAbsolutePath().toString()));
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
StartLog.warn(t);
|
||||
failures.add(String.format("[%s] %s - %s",t.getClass().getSimpleName(),t.getMessage(),file.toAbsolutePath().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartLog.warn("Failed to process all file resources.");
|
||||
for (String failure : failures)
|
||||
{
|
||||
StartLog.warn(" - %s",failure);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean processFileResource(List<FileInitializer> fileInitializers, StartArgs args, FileArg arg, Path file) throws IOException
|
||||
{
|
||||
if (args.isDownload() && arg.uri != null)
|
||||
{
|
||||
URI uri = URI.create(arg.uri);
|
||||
|
||||
// Process via initializers
|
||||
for (FileInitializer finit : fileInitializers)
|
||||
{
|
||||
if (finit.init(uri,file))
|
||||
{
|
||||
// Completed successfully
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Process directly
|
||||
boolean isDir = arg.location.endsWith("/");
|
||||
|
||||
if (FS.exists(file))
|
||||
{
|
||||
// Validate existence
|
||||
if (isDir)
|
||||
{
|
||||
if (!Files.isDirectory(file))
|
||||
{
|
||||
throw new IOException("Invalid: path should be a directory (but isn't): " + file);
|
||||
}
|
||||
if (!FS.canReadDirectory(file))
|
||||
{
|
||||
throw new IOException("Unable to read directory: " + file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!FS.canReadFile(file))
|
||||
{
|
||||
throw new IOException("Unable to read file: " + file);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isDir)
|
||||
{
|
||||
// Create directory
|
||||
StartLog.log("MKDIR",baseHome.toShortForm(file));
|
||||
FS.ensureDirectoryExists(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Warn on missing file (this has to be resolved manually by
|
||||
// user)
|
||||
String shortRef = baseHome.toShortForm(file);
|
||||
if (args.isTestingModeEnabled())
|
||||
{
|
||||
StartLog.log("TESTING MODE","Skipping required file check on: %s",shortRef);
|
||||
return true;
|
||||
}
|
||||
|
||||
StartLog.warn("Missing Required File: %s",baseHome.toShortForm(file));
|
||||
args.setRun(false);
|
||||
if (arg.uri != null)
|
||||
{
|
||||
StartLog.warn(" Can be downloaded From: %s",arg.uri);
|
||||
StartLog.warn(" Run start.jar --create-files to download");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void start(StartArgs args) throws IOException, InterruptedException
|
||||
{
|
||||
StartLog.debug("StartArgs: %s",args);
|
||||
|
@ -740,74 +377,13 @@ public class Main
|
|||
doStop(args);
|
||||
}
|
||||
|
||||
// Establish FileInitializers
|
||||
List<FileInitializer> fileInitializers = new ArrayList<FileInitializer>();
|
||||
if (args.isTestingModeEnabled())
|
||||
BaseBuilder baseBuilder = new BaseBuilder(baseHome,args);
|
||||
if(baseBuilder.build())
|
||||
{
|
||||
// No downloads performed
|
||||
fileInitializers.add(new TestFileInitializer());
|
||||
// base directory changed.
|
||||
StartLog.info("Base directory was modified");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Downloads are allowed to be performed
|
||||
|
||||
// Setup Maven Local Repo
|
||||
Path localRepoDir = args.getMavenLocalRepoDir();
|
||||
if (localRepoDir != null)
|
||||
{
|
||||
// Use provided local repo directory
|
||||
fileInitializers.add(new MavenLocalRepoFileInitializer(localRepoDir));
|
||||
}
|
||||
else
|
||||
{
|
||||
// No no local repo directory (direct downloads)
|
||||
fileInitializers.add(new MavenLocalRepoFileInitializer());
|
||||
}
|
||||
|
||||
// Normal URL downloads
|
||||
fileInitializers.add(new UriFileInitializer());
|
||||
}
|
||||
|
||||
boolean rebuildGraph = false;
|
||||
|
||||
// Initialize start.ini
|
||||
for (String module : args.getAddToStartIni())
|
||||
{
|
||||
buildIni(fileInitializers,args,module,true,true);
|
||||
rebuildGraph = true;
|
||||
}
|
||||
|
||||
// Initialize start.d
|
||||
for (String module : args.getAddToStartdIni())
|
||||
{
|
||||
buildIni(fileInitializers,args,module,true,false);
|
||||
rebuildGraph = true;
|
||||
}
|
||||
|
||||
if (rebuildGraph)
|
||||
{
|
||||
args.getAllModules().clearMissing();
|
||||
args.getAllModules().buildGraph();
|
||||
}
|
||||
|
||||
// If in --create-files, check licenses
|
||||
if(args.isDownload())
|
||||
{
|
||||
if (!args.isApproveAllLicenses())
|
||||
{
|
||||
StartLog.debug("Requesting License Acknowledgement");
|
||||
for (Module module : args.getAllModules().resolveEnabled())
|
||||
{
|
||||
if (!module.acknowledgeLicense())
|
||||
{
|
||||
StartLog.warn(EXITING_LICENSE_NOT_ACKNOWLEDGED);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processFileResources(fileInitializers, args);
|
||||
|
||||
// Informational command line, don't run jetty
|
||||
if (!args.isRun())
|
||||
|
@ -860,8 +436,6 @@ public class Main
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void doStop(StartArgs args)
|
||||
{
|
||||
int stopPort = Integer.parseInt(args.getProperties().getString("STOP.PORT"));
|
||||
|
|
|
@ -108,7 +108,7 @@ public class Module
|
|||
/** License lines */
|
||||
private List<String> license;
|
||||
|
||||
/** Is this Module enabled via start.jar command line, start.ini, or start.d/*.ini ? */
|
||||
/** Is this Module enabled via start.jar command line, start.ini, or start.d/*.ini */
|
||||
private boolean enabled = false;
|
||||
/** List of sources that enabled this module */
|
||||
private final Set<String> sources = new HashSet<>();
|
||||
|
@ -272,6 +272,29 @@ public class Module
|
|||
{
|
||||
return license != null && license.size() > 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasSource(String regex)
|
||||
{
|
||||
for (String source : sources)
|
||||
{
|
||||
if (source.matches(regex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasUniqueSource(String regex)
|
||||
{
|
||||
if (sources.size() != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return sources.iterator().next().matches(regex);
|
||||
}
|
||||
|
||||
public boolean acknowledgeLicense() throws IOException
|
||||
{
|
||||
|
@ -361,6 +384,11 @@ public class Module
|
|||
return enabled;
|
||||
}
|
||||
|
||||
public boolean isVirtual()
|
||||
{
|
||||
return !logicalName.equals(fileRef);
|
||||
}
|
||||
|
||||
public void process(BaseHome basehome) throws FileNotFoundException, IOException
|
||||
{
|
||||
Pattern section = Pattern.compile("\\s*\\[([^]]*)\\]\\s*");
|
||||
|
@ -477,5 +505,4 @@ public class Module
|
|||
str.append(']');
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.io.IOException;
|
|||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -38,6 +39,134 @@ import java.util.regex.Pattern;
|
|||
*/
|
||||
public class Modules implements Iterable<Module>
|
||||
{
|
||||
public static interface Matcher
|
||||
{
|
||||
public boolean match(Module module);
|
||||
}
|
||||
|
||||
public static class AllMatcher implements Matcher
|
||||
{
|
||||
@Override
|
||||
public boolean match(Module module)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AndMatcher implements Matcher
|
||||
{
|
||||
private final Matcher matchers[];
|
||||
|
||||
public AndMatcher(Matcher ... matchers)
|
||||
{
|
||||
this.matchers = matchers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(Module module)
|
||||
{
|
||||
for (Matcher matcher : this.matchers)
|
||||
{
|
||||
if (!matcher.match(module))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EnabledMatcher implements Matcher
|
||||
{
|
||||
@Override
|
||||
public boolean match(Module module)
|
||||
{
|
||||
return module.isEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RegexNameMatcher implements Matcher
|
||||
{
|
||||
private final Pattern pat;
|
||||
|
||||
public RegexNameMatcher(String regex)
|
||||
{
|
||||
this.pat = Pattern.compile(regex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(Module module)
|
||||
{
|
||||
return pat.matcher(module.getName()).matches();
|
||||
}
|
||||
}
|
||||
|
||||
public static class UniqueSourceMatcher implements Matcher
|
||||
{
|
||||
private final Pattern pat;
|
||||
|
||||
public UniqueSourceMatcher(String sourceRegex)
|
||||
{
|
||||
this.pat = Pattern.compile(sourceRegex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(Module module)
|
||||
{
|
||||
if (module.getSources().size() != 1)
|
||||
{
|
||||
// Not unique
|
||||
return false;
|
||||
}
|
||||
|
||||
String sourceId = module.getSources().iterator().next();
|
||||
return pat.matcher(sourceId).matches();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SourceSetMatcher implements Matcher
|
||||
{
|
||||
private final Set<String> nameSet;
|
||||
|
||||
public SourceSetMatcher(String... names)
|
||||
{
|
||||
this.nameSet = new HashSet<>();
|
||||
|
||||
for (String name : names)
|
||||
{
|
||||
this.nameSet.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(Module module)
|
||||
{
|
||||
Set<String> sources = module.getSources();
|
||||
if (sources == null)
|
||||
{
|
||||
// empty sources list
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sources.size() != nameSet.size())
|
||||
{
|
||||
// non-equal sized set
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String source : module.getSources())
|
||||
{
|
||||
if (!this.nameSet.contains(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final BaseHome baseHome;
|
||||
private final StartArgs args;
|
||||
|
||||
|
@ -194,7 +323,7 @@ public class Modules implements Iterable<Module>
|
|||
ordered.addAll(modules.values());
|
||||
Collections.sort(ordered,new Module.NameComparator());
|
||||
|
||||
List<Module> active = resolveEnabled();
|
||||
List<Module> active = getEnabled();
|
||||
|
||||
for (Module module : ordered)
|
||||
{
|
||||
|
@ -275,37 +404,40 @@ public class Modules implements Iterable<Module>
|
|||
List<String> empty = Collections.emptyList();
|
||||
enable(name,empty);
|
||||
}
|
||||
|
||||
|
||||
public void enable(String name, List<String> sources) throws IOException
|
||||
public int enableAll(List<String> names, String source) throws IOException
|
||||
{
|
||||
if ((names == null) || (names.isEmpty()))
|
||||
{
|
||||
// nothing to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<String> sources = Collections.singletonList(source);
|
||||
|
||||
int count = 0;
|
||||
for (String name : names)
|
||||
{
|
||||
count += enable(name,sources);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public int enable(String name, List<String> sources) throws IOException
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (name.contains("*"))
|
||||
{
|
||||
// A regex!
|
||||
Pattern pat = Pattern.compile(name);
|
||||
List<Module> matching = new ArrayList<>();
|
||||
do
|
||||
List<Module> matching = getMatching(new RegexNameMatcher(name));
|
||||
|
||||
// enable them
|
||||
for (Module module : matching)
|
||||
{
|
||||
matching.clear();
|
||||
|
||||
// find matching entries that are not enabled
|
||||
for (Map.Entry<String, Module> entry : modules.entrySet())
|
||||
{
|
||||
if (pat.matcher(entry.getKey()).matches())
|
||||
{
|
||||
if (!entry.getValue().isEnabled())
|
||||
{
|
||||
matching.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// enable them
|
||||
for (Module module : matching)
|
||||
{
|
||||
enableModule(module,sources);
|
||||
}
|
||||
count += enableModule(module,sources);
|
||||
}
|
||||
while (!matching.isEmpty());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -313,32 +445,36 @@ public class Modules implements Iterable<Module>
|
|||
if (module == null)
|
||||
{
|
||||
System.err.printf("WARNING: Cannot enable requested module [%s]: not a valid module name.%n",name);
|
||||
return;
|
||||
return count;
|
||||
}
|
||||
enableModule(module,sources);
|
||||
count += enableModule(module,sources);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private void enableModule(Module module, List<String> sources) throws IOException
|
||||
private int enableModule(Module module, List<String> sources) throws IOException
|
||||
{
|
||||
String via = "<transitive>";
|
||||
|
||||
// Always add the sources
|
||||
if (sources != null)
|
||||
int count = 0;
|
||||
if(sources == null)
|
||||
{
|
||||
module.addSources(sources);
|
||||
via = Utils.join(sources, ", ");
|
||||
// We use source for tagging how a node was selected, it should
|
||||
// always be required
|
||||
throw new RuntimeException("sources should never be empty");
|
||||
}
|
||||
|
||||
module.addSources(sources);
|
||||
String via = Utils.join(sources, ", ");
|
||||
|
||||
// If already enabled, nothing else to do
|
||||
if (module.isEnabled())
|
||||
{
|
||||
StartLog.debug("Enabled module: %s (via %s)",module.getName(),via);
|
||||
return;
|
||||
return count;
|
||||
}
|
||||
|
||||
StartLog.debug("Enabling module: %s (via %s)",module.getName(),via);
|
||||
module.setEnabled(true);
|
||||
count++;
|
||||
args.parseModule(module);
|
||||
module.expandProperties(args.getProperties());
|
||||
|
||||
|
@ -370,9 +506,10 @@ public class Modules implements Iterable<Module>
|
|||
}
|
||||
if (parent != null)
|
||||
{
|
||||
enableModule(parent,null);
|
||||
count += enableModule(parent,sources);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private void findChildren(Module module, Set<Module> ret)
|
||||
|
@ -560,12 +697,40 @@ public class Modules implements Iterable<Module>
|
|||
findChildren(module,ret);
|
||||
return asNameSet(ret);
|
||||
}
|
||||
|
||||
public List<Module> getEnabled()
|
||||
{
|
||||
return getMatching(new EnabledMatcher());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the execution order of the enabled modules, and all dependant modules, based on depth first transitive reduction.
|
||||
* Get the modules from the tree that match the provided matcher.
|
||||
*
|
||||
* @return the list of active modules (plus dependant modules), in execution order.
|
||||
* @param matcher the matcher to use for matches
|
||||
* @return the list of matching modules in execution order.
|
||||
*/
|
||||
public List<Module> getMatching(Matcher matcher)
|
||||
{
|
||||
List<Module> selected = new ArrayList<Module>();
|
||||
|
||||
for (Module module : modules.values())
|
||||
{
|
||||
if (matcher.match(module))
|
||||
{
|
||||
selected.add(module);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(selected,new Module.DepthComparator());
|
||||
return selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the execution order of the enabled modules, and all dependent modules, based on depth first transitive reduction.
|
||||
*
|
||||
* @return the list of active modules (plus dependent modules), in execution order.
|
||||
*/
|
||||
@Deprecated
|
||||
public List<Module> resolveEnabled()
|
||||
{
|
||||
Map<String, Module> active = new HashMap<String, Module>();
|
||||
|
@ -578,6 +743,16 @@ public class Modules implements Iterable<Module>
|
|||
}
|
||||
}
|
||||
|
||||
assertModulesValid(active.values());
|
||||
|
||||
List<Module> ordered = new ArrayList<>();
|
||||
ordered.addAll(active.values());
|
||||
Collections.sort(ordered,new Module.DepthComparator());
|
||||
return ordered;
|
||||
}
|
||||
|
||||
public void assertModulesValid(Collection<Module> active)
|
||||
{
|
||||
/*
|
||||
* check against the missing modules
|
||||
*
|
||||
|
@ -585,9 +760,9 @@ public class Modules implements Iterable<Module>
|
|||
*/
|
||||
for (String missing : missingModules)
|
||||
{
|
||||
for (String activeModule : active.keySet())
|
||||
for (Module module : active)
|
||||
{
|
||||
if (missing.startsWith(activeModule))
|
||||
if (missing.startsWith(module.getName()))
|
||||
{
|
||||
StartLog.warn("** Unable to continue, required dependency missing. [%s]",missing);
|
||||
StartLog.warn("** As configured, Jetty is unable to start due to a missing enabled module dependency.");
|
||||
|
@ -596,11 +771,6 @@ public class Modules implements Iterable<Module>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Module> ordered = new ArrayList<>();
|
||||
ordered.addAll(active.values());
|
||||
Collections.sort(ordered,new Module.DepthComparator());
|
||||
return ordered;
|
||||
}
|
||||
|
||||
public Set<String> resolveParentModulesOf(String moduleName)
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
Jetty start
|
||||
-----------
|
||||
|
||||
The run directory is either the top-level of a distribution
|
||||
or jetty-distribution/target/distribution directory when built from
|
||||
source.
|
||||
|
||||
Jetty start.jar provides a cross platform replacement for startup scripts.
|
||||
It makes use of executable JAR that builds the classpath and then executes
|
||||
jetty.
|
||||
|
||||
To run with the demo:
|
||||
|
||||
java -jar start.jar --enable=demo
|
||||
java -jar start.jar
|
||||
|
||||
To run with the default modules:
|
||||
|
||||
java -jar start.jar
|
||||
|
||||
The default options may be specified in the start.ini file, or if
|
||||
that is not present, they are defined in the start.config file that
|
||||
is within the start.jar.
|
||||
|
||||
To run with specific configuration file(s)
|
||||
|
||||
java -jar start.jar etc/jetty.xml
|
||||
|
||||
To see the available options
|
||||
|
||||
java -jar start.jar --help
|
||||
|
||||
To run with JSP support (if available)
|
||||
|
||||
java -jar start.jar --module=jsp
|
||||
|
||||
To run with JMX support
|
||||
|
||||
java -jar start.jar --module=jmx
|
||||
|
||||
To run with JSP & JMX support
|
||||
|
||||
java -jar start.jar --module=jsp,jmx
|
||||
|
||||
Note that JSP requires the jasper jars to be within $JETTY/lib/jsp These
|
||||
are currently not distributed with the eclipse release and must be
|
||||
obtained from a jetty-hightide release from codehaus.
|
||||
|
|
@ -116,6 +116,7 @@ public class StartArgs
|
|||
|
||||
/** Download related args */
|
||||
private boolean download = false;
|
||||
private boolean licenseCheckRequired = false;
|
||||
private boolean testingMode = false;
|
||||
|
||||
private boolean help = false;
|
||||
|
@ -139,10 +140,6 @@ public class StartArgs
|
|||
FileArg arg = new FileArg(module, uriLocation);
|
||||
if (!files.contains(arg))
|
||||
{
|
||||
if (arg.uri != null)
|
||||
{
|
||||
this.download = true;
|
||||
}
|
||||
files.add(arg);
|
||||
}
|
||||
}
|
||||
|
@ -656,6 +653,11 @@ public class StartArgs
|
|||
return exec;
|
||||
}
|
||||
|
||||
public boolean isLicenseCheckRequired()
|
||||
{
|
||||
return licenseCheckRequired;
|
||||
}
|
||||
|
||||
public boolean isNormalMainClass()
|
||||
{
|
||||
return SERVER_MAIN.equals(getMainClassname());
|
||||
|
@ -792,6 +794,7 @@ public class StartArgs
|
|||
{
|
||||
run = false;
|
||||
download = true;
|
||||
licenseCheckRequired = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -861,6 +864,7 @@ public class StartArgs
|
|||
addToStartdIni.addAll(moduleNames);
|
||||
run = false;
|
||||
download = true;
|
||||
licenseCheckRequired = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -871,6 +875,7 @@ public class StartArgs
|
|||
addToStartIni.addAll(moduleNames);
|
||||
run = false;
|
||||
download = true;
|
||||
licenseCheckRequired = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.start.builders;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import org.eclipse.jetty.start.BaseBuilder;
|
||||
import org.eclipse.jetty.start.FS;
|
||||
import org.eclipse.jetty.start.Module;
|
||||
|
||||
/**
|
||||
* Management of the <code>${jetty.base}/start.d/</code> based configuration.
|
||||
* <p>
|
||||
* Implementation of the <code>--add-to-startd=[name]</code> command line behavior
|
||||
*/
|
||||
public class StartDirBuilder implements BaseBuilder.Config
|
||||
{
|
||||
private final Path startDir;
|
||||
|
||||
public StartDirBuilder(BaseBuilder baseBuilder) throws IOException
|
||||
{
|
||||
this.startDir = baseBuilder.getBaseHome().getBasePath("start.d");
|
||||
FS.ensureDirectoryExists(startDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addModule(Module module) throws IOException
|
||||
{
|
||||
if (module.isVirtual())
|
||||
{
|
||||
// skip, no need to reference
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create start.d/{name}.ini
|
||||
|
||||
Path ini = startDir.resolve(module.getName() + ".ini");
|
||||
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(ini,StandardCharsets.UTF_8,StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING))
|
||||
{
|
||||
writeModuleSection(writer,module);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void writeModuleSection(BufferedWriter writer, Module module)
|
||||
{
|
||||
PrintWriter out = new PrintWriter(writer);
|
||||
|
||||
out.println("# --------------------------------------- ");
|
||||
out.println("# Module: " + module.getName());
|
||||
|
||||
out.println("--module=" + module.getName());
|
||||
|
||||
for (String line : module.getDefaultConfig())
|
||||
{
|
||||
out.println(line);
|
||||
}
|
||||
|
||||
out.println();
|
||||
out.flush();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.start.builders;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.start.BaseBuilder;
|
||||
import org.eclipse.jetty.start.Module;
|
||||
import org.eclipse.jetty.start.Props;
|
||||
|
||||
/**
|
||||
* Management of the <code>${jetty.base}/start.ini</code> based configuration.
|
||||
* <p>
|
||||
* Implementation of the <code>--add-to-start=[name]</code> command line
|
||||
* behavior
|
||||
*/
|
||||
public class StartIniBuilder implements BaseBuilder.Config
|
||||
{
|
||||
private final Path startIni;
|
||||
|
||||
/* List of modules already present in start.ini */
|
||||
private Set<String> modulesPresent = new HashSet<>();
|
||||
|
||||
/* List of properties (keys only) already present in start.ini */
|
||||
private Set<String> propsPresent = new HashSet<>();
|
||||
|
||||
public StartIniBuilder(BaseBuilder baseBuilder) throws IOException
|
||||
{
|
||||
this.startIni = baseBuilder.getBaseHome().getBasePath("start.ini");
|
||||
|
||||
if (Files.exists(startIni))
|
||||
{
|
||||
parseIni();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseIni() throws IOException
|
||||
{
|
||||
try (BufferedReader reader = Files.newBufferedReader(startIni,StandardCharsets.UTF_8))
|
||||
{
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
line = line.trim();
|
||||
if (line.startsWith("--module="))
|
||||
{
|
||||
List<String> moduleNames = Props.getValues(line);
|
||||
this.modulesPresent.addAll(moduleNames);
|
||||
}
|
||||
else if (!line.startsWith("-") && line.contains("-"))
|
||||
{
|
||||
String key = line.substring(0,line.indexOf('='));
|
||||
this.propsPresent.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addModule(Module module) throws IOException
|
||||
{
|
||||
if (modulesPresent.contains(module.getName()))
|
||||
{
|
||||
// skip, already present
|
||||
return false;
|
||||
}
|
||||
|
||||
if (module.isVirtual())
|
||||
{
|
||||
// skip, no need to reference
|
||||
return false;
|
||||
}
|
||||
|
||||
// Append to start.ini
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(startIni,StandardCharsets.UTF_8,StandardOpenOption.APPEND,StandardOpenOption.CREATE))
|
||||
{
|
||||
writeModuleSection(writer,module);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void writeModuleSection(BufferedWriter writer, Module module)
|
||||
{
|
||||
PrintWriter out = new PrintWriter(writer);
|
||||
|
||||
out.println("# --------------------------------------- ");
|
||||
out.println("# Module: " + module.getName());
|
||||
|
||||
out.println("--module=" + module.getName());
|
||||
|
||||
for (String line : module.getDefaultConfig())
|
||||
{
|
||||
// TODO: validate property keys
|
||||
out.println(line);
|
||||
}
|
||||
|
||||
out.println();
|
||||
out.flush();
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import java.net.URI;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.jetty.start.BaseHome;
|
||||
import org.eclipse.jetty.start.FS;
|
||||
import org.eclipse.jetty.start.FileInitializer;
|
||||
import org.eclipse.jetty.start.StartLog;
|
||||
|
@ -80,13 +81,14 @@ public class MavenLocalRepoFileInitializer extends UriFileInitializer implements
|
|||
|
||||
private Path localRepositoryDir;
|
||||
|
||||
public MavenLocalRepoFileInitializer()
|
||||
public MavenLocalRepoFileInitializer(BaseHome baseHome)
|
||||
{
|
||||
this(null);
|
||||
this(baseHome,null);
|
||||
}
|
||||
|
||||
public MavenLocalRepoFileInitializer(Path localRepoDir)
|
||||
public MavenLocalRepoFileInitializer(BaseHome baseHome, Path localRepoDir)
|
||||
{
|
||||
super(baseHome);
|
||||
this.localRepositoryDir = localRepoDir;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import org.eclipse.jetty.start.BaseHome;
|
||||
import org.eclipse.jetty.start.FS;
|
||||
import org.eclipse.jetty.start.FileInitializer;
|
||||
import org.eclipse.jetty.start.StartLog;
|
||||
|
@ -34,6 +35,12 @@ import org.eclipse.jetty.start.StartLog;
|
|||
public class UriFileInitializer implements FileInitializer
|
||||
{
|
||||
private final static String[] SUPPORTED_SCHEMES = { "http", "https" };
|
||||
private final BaseHome baseHome;
|
||||
|
||||
public UriFileInitializer(BaseHome baseHome)
|
||||
{
|
||||
this.baseHome = baseHome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init(URI uri, Path file) throws IOException
|
||||
|
@ -57,7 +64,7 @@ public class UriFileInitializer implements FileInitializer
|
|||
|
||||
protected void download(URI uri, Path file) throws IOException
|
||||
{
|
||||
StartLog.log("DOWNLOAD","%s to %s",uri,file);
|
||||
StartLog.log("DOWNLOAD","%s to %s",uri,baseHome.toShortForm(file));
|
||||
|
||||
FS.ensureDirectoryExists(file.getParent());
|
||||
|
||||
|
|
|
@ -18,21 +18,25 @@
|
|||
|
||||
package org.eclipse.jetty.start;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.start.Modules.AndMatcher;
|
||||
import org.eclipse.jetty.start.Modules.EnabledMatcher;
|
||||
import org.eclipse.jetty.start.Modules.UniqueSourceMatcher;
|
||||
import org.eclipse.jetty.start.config.CommandLineConfigSource;
|
||||
import org.eclipse.jetty.start.config.ConfigSources;
|
||||
import org.eclipse.jetty.start.config.JettyBaseConfigSource;
|
||||
import org.eclipse.jetty.start.config.JettyHomeConfigSource;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -49,18 +53,18 @@ public class ModulesTest
|
|||
// Test Env
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home");
|
||||
File baseDir = testdir.getEmptyDir();
|
||||
String cmdLine[] = new String[] {"jetty.version=TEST"};
|
||||
|
||||
String cmdLine[] = new String[] { "jetty.version=TEST" };
|
||||
|
||||
// Configuration
|
||||
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(cmdLineSource);
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
|
||||
|
||||
// Initialize
|
||||
BaseHome basehome = new BaseHome(config);
|
||||
|
||||
|
||||
StartArgs args = new StartArgs();
|
||||
args.parse(config);
|
||||
|
||||
|
@ -112,14 +116,14 @@ public class ModulesTest
|
|||
expected.add("server");
|
||||
expected.add("annotations");
|
||||
expected.add("resources");
|
||||
expected.add("logging");
|
||||
|
||||
expected.add("logging");
|
||||
|
||||
ConfigurationAssert.assertContainsUnordered("All Modules",expected,moduleNames);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test loading of only shallow modules, not deep references.
|
||||
* In other words. ${search-dir}/modules/*.mod should be the only
|
||||
* In other words. ${search-dir}/modules/*.mod should be the only
|
||||
* valid references, but ${search-dir}/alt/foo/modules/*.mod should
|
||||
* not be considered valid.
|
||||
*/
|
||||
|
@ -128,20 +132,21 @@ public class ModulesTest
|
|||
{
|
||||
// Test Env
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("jetty home with spaces");
|
||||
// intentionally setup top level resources dir (as this would have many deep references)
|
||||
// intentionally setup top level resources dir (as this would have many
|
||||
// deep references)
|
||||
File baseDir = MavenTestingUtils.getTestResourcesDir();
|
||||
String cmdLine[] = new String[] {"jetty.version=TEST"};
|
||||
|
||||
String cmdLine[] = new String[] { "jetty.version=TEST" };
|
||||
|
||||
// Configuration
|
||||
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(cmdLineSource);
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
|
||||
|
||||
// Initialize
|
||||
BaseHome basehome = new BaseHome(config);
|
||||
|
||||
|
||||
StartArgs args = new StartArgs();
|
||||
args.parse(config);
|
||||
|
||||
|
@ -154,10 +159,10 @@ public class ModulesTest
|
|||
{
|
||||
moduleNames.add(mod.getName());
|
||||
}
|
||||
|
||||
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("base");
|
||||
|
||||
|
||||
ConfigurationAssert.assertContainsUnordered("All Modules",expected,moduleNames);
|
||||
}
|
||||
|
||||
|
@ -167,18 +172,18 @@ public class ModulesTest
|
|||
// Test Env
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home");
|
||||
File baseDir = testdir.getEmptyDir();
|
||||
String cmdLine[] = new String[] {"jetty.version=TEST", "java.version=1.7.0_60"};
|
||||
|
||||
String cmdLine[] = new String[] { "jetty.version=TEST", "java.version=1.7.0_60" };
|
||||
|
||||
// Configuration
|
||||
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(cmdLineSource);
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
|
||||
|
||||
// Initialize
|
||||
BaseHome basehome = new BaseHome(config);
|
||||
|
||||
|
||||
StartArgs args = new StartArgs();
|
||||
args.parse(config);
|
||||
|
||||
|
@ -206,9 +211,9 @@ public class ModulesTest
|
|||
expected.add("protonego-impl");
|
||||
expected.add("xml");
|
||||
expected.add("jsp-impl");
|
||||
|
||||
|
||||
List<String> resolved = new ArrayList<>();
|
||||
for (Module module : modules.resolveEnabled())
|
||||
for (Module module : modules.getEnabled())
|
||||
{
|
||||
resolved.add(module.getName());
|
||||
}
|
||||
|
@ -222,23 +227,23 @@ public class ModulesTest
|
|||
// Test Env
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home");
|
||||
File baseDir = testdir.getEmptyDir();
|
||||
String cmdLine[] = new String[] {"jetty.version=TEST"};
|
||||
|
||||
String cmdLine[] = new String[] { "jetty.version=TEST" };
|
||||
|
||||
// Configuration
|
||||
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(cmdLineSource);
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
|
||||
|
||||
// Initialize
|
||||
BaseHome basehome = new BaseHome(config);
|
||||
|
||||
|
||||
StartArgs args = new StartArgs();
|
||||
args.parse(config);
|
||||
|
||||
// Test Modules
|
||||
Modules modules = new Modules(basehome, args);
|
||||
Modules modules = new Modules(basehome,args);
|
||||
modules.registerAll();
|
||||
|
||||
// Enable 2 modules
|
||||
|
@ -248,7 +253,7 @@ public class ModulesTest
|
|||
modules.buildGraph();
|
||||
|
||||
// Collect active module list
|
||||
List<Module> active = modules.resolveEnabled();
|
||||
List<Module> active = modules.getEnabled();
|
||||
|
||||
// Assert names are correct, and in the right order
|
||||
List<String> expectedNames = new ArrayList<>();
|
||||
|
@ -263,7 +268,7 @@ public class ModulesTest
|
|||
actualNames.add(actual.getName());
|
||||
}
|
||||
|
||||
Assert.assertThat("Resolved Names: " + actualNames,actualNames,contains(expectedNames.toArray()));
|
||||
assertThat("Resolved Names: " + actualNames,actualNames,contains(expectedNames.toArray()));
|
||||
|
||||
// Assert Library List
|
||||
List<String> expectedLibs = new ArrayList<>();
|
||||
|
@ -277,7 +282,7 @@ public class ModulesTest
|
|||
expectedLibs.add("lib/jetty-server-${jetty.version}.jar");
|
||||
|
||||
List<String> actualLibs = modules.normalizeLibs(active);
|
||||
Assert.assertThat("Resolved Libs: " + actualLibs,actualLibs,contains(expectedLibs.toArray()));
|
||||
assertThat("Resolved Libs: " + actualLibs,actualLibs,contains(expectedLibs.toArray()));
|
||||
|
||||
// Assert XML List
|
||||
List<String> expectedXmls = new ArrayList<>();
|
||||
|
@ -285,7 +290,7 @@ public class ModulesTest
|
|||
expectedXmls.add("etc/jetty-http.xml");
|
||||
|
||||
List<String> actualXmls = modules.normalizeXmls(active);
|
||||
Assert.assertThat("Resolved XMLs: " + actualXmls,actualXmls,contains(expectedXmls.toArray()));
|
||||
assertThat("Resolved XMLs: " + actualXmls,actualXmls,contains(expectedXmls.toArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -294,18 +299,18 @@ public class ModulesTest
|
|||
// Test Env
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home");
|
||||
File baseDir = testdir.getEmptyDir();
|
||||
String cmdLine[] = new String[] {"jetty.version=TEST"};
|
||||
|
||||
String cmdLine[] = new String[] { "jetty.version=TEST" };
|
||||
|
||||
// Configuration
|
||||
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(cmdLineSource);
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
|
||||
|
||||
// Initialize
|
||||
BaseHome basehome = new BaseHome(config);
|
||||
|
||||
|
||||
StartArgs args = new StartArgs();
|
||||
args.parse(config);
|
||||
|
||||
|
@ -321,7 +326,7 @@ public class ModulesTest
|
|||
// modules.dump();
|
||||
|
||||
// Collect active module list
|
||||
List<Module> active = modules.resolveEnabled();
|
||||
List<Module> active = modules.getEnabled();
|
||||
|
||||
// Assert names are correct, and in the right order
|
||||
List<String> expectedNames = new ArrayList<>();
|
||||
|
@ -341,7 +346,7 @@ public class ModulesTest
|
|||
actualNames.add(actual.getName());
|
||||
}
|
||||
|
||||
Assert.assertThat("Resolved Names: " + actualNames,actualNames,contains(expectedNames.toArray()));
|
||||
assertThat("Resolved Names: " + actualNames,actualNames,contains(expectedNames.toArray()));
|
||||
|
||||
// Assert Library List
|
||||
List<String> expectedLibs = new ArrayList<>();
|
||||
|
@ -362,7 +367,7 @@ public class ModulesTest
|
|||
expectedLibs.add("lib/websocket/*.jar");
|
||||
|
||||
List<String> actualLibs = modules.normalizeLibs(active);
|
||||
Assert.assertThat("Resolved Libs: " + actualLibs,actualLibs,contains(expectedLibs.toArray()));
|
||||
assertThat("Resolved Libs: " + actualLibs,actualLibs,contains(expectedLibs.toArray()));
|
||||
|
||||
// Assert XML List
|
||||
List<String> expectedXmls = new ArrayList<>();
|
||||
|
@ -373,6 +378,98 @@ public class ModulesTest
|
|||
expectedXmls.add("etc/jetty-websockets.xml");
|
||||
|
||||
List<String> actualXmls = modules.normalizeXmls(active);
|
||||
Assert.assertThat("Resolved XMLs: " + actualXmls,actualXmls,contains(expectedXmls.toArray()));
|
||||
assertThat("Resolved XMLs: " + actualXmls,actualXmls,contains(expectedXmls.toArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolve_Alt() throws IOException
|
||||
{
|
||||
// Test Env
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home");
|
||||
File baseDir = testdir.getEmptyDir();
|
||||
String cmdLine[] = new String[] { "jetty.version=TEST" };
|
||||
|
||||
// Configuration
|
||||
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(cmdLineSource);
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
|
||||
// Initialize
|
||||
BaseHome basehome = new BaseHome(config);
|
||||
|
||||
StartArgs args = new StartArgs();
|
||||
args.parse(config);
|
||||
|
||||
// Test Modules
|
||||
Modules modules = new Modules(basehome,args);
|
||||
modules.registerAll();
|
||||
|
||||
// Enable test modules
|
||||
modules.enable("http",TEST_SOURCE);
|
||||
modules.enable("annotations",TEST_SOURCE);
|
||||
modules.enable("deploy",TEST_SOURCE);
|
||||
// Enable alternate modules
|
||||
String alt = "<alt>";
|
||||
modules.enable("websocket",Collections.singletonList(alt));
|
||||
modules.enable("jsp",Collections.singletonList(alt));
|
||||
|
||||
modules.buildGraph();
|
||||
// modules.dump();
|
||||
|
||||
// Collect active module list
|
||||
List<Module> active = modules.getEnabled();
|
||||
|
||||
// Assert names are correct, and in the right order
|
||||
List<String> expectedNames = new ArrayList<>();
|
||||
expectedNames.add("base");
|
||||
expectedNames.add("jsp-impl");
|
||||
expectedNames.add("xml");
|
||||
expectedNames.add("server");
|
||||
expectedNames.add("http");
|
||||
expectedNames.add("jndi");
|
||||
expectedNames.add("security");
|
||||
expectedNames.add("servlet");
|
||||
expectedNames.add("jsp");
|
||||
expectedNames.add("plus");
|
||||
expectedNames.add("webapp");
|
||||
expectedNames.add("annotations");
|
||||
expectedNames.add("deploy");
|
||||
expectedNames.add("websocket");
|
||||
|
||||
List<String> actualNames = new ArrayList<>();
|
||||
for (Module actual : active)
|
||||
{
|
||||
actualNames.add(actual.getName());
|
||||
}
|
||||
|
||||
assertThat("Resolved Names: " + actualNames,actualNames,contains(expectedNames.toArray()));
|
||||
|
||||
// Now work with the 'alt' selected
|
||||
List<String> expectedAlts = new ArrayList<>();
|
||||
expectedAlts.add("jsp-impl");
|
||||
expectedAlts.add("jsp");
|
||||
expectedAlts.add("websocket");
|
||||
|
||||
for (String expectedAlt : expectedAlts)
|
||||
{
|
||||
Module altMod = modules.get(expectedAlt);
|
||||
assertThat("Alt.mod[" + expectedAlt + "].enabled",altMod.isEnabled(),is(true));
|
||||
Set<String> sources = altMod.getSources();
|
||||
assertThat("Alt.mod[" + expectedAlt + "].sources: [" + Utils.join(sources,", ") + "]",sources,contains(alt));
|
||||
}
|
||||
|
||||
// Now collect the unique source list
|
||||
List<Module> alts = modules.getMatching(new AndMatcher(new EnabledMatcher(),new UniqueSourceMatcher(alt)));
|
||||
|
||||
// Assert names are correct, and in the right order
|
||||
actualNames = new ArrayList<>();
|
||||
for (Module actual : alts)
|
||||
{
|
||||
actualNames.add(actual.getName());
|
||||
}
|
||||
|
||||
assertThat("Resolved Alt (Sources) Names: " + actualNames,actualNames,contains(expectedAlts.toArray()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,17 @@ package org.eclipse.jetty.start.fileinits;
|
|||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.start.BaseHome;
|
||||
import org.eclipse.jetty.start.config.ConfigSources;
|
||||
import org.eclipse.jetty.start.config.JettyBaseConfigSource;
|
||||
import org.eclipse.jetty.start.config.JettyHomeConfigSource;
|
||||
import org.eclipse.jetty.start.fileinits.MavenLocalRepoFileInitializer.Coordinates;
|
||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
@ -32,11 +40,28 @@ public class MavenLocalRepoFileInitializerTest
|
|||
{
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
|
||||
private BaseHome baseHome;
|
||||
|
||||
@Before
|
||||
public void setupBaseHome() throws IOException
|
||||
{
|
||||
File homeDir = testdir.getEmptyDir();
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
config.add(new JettyBaseConfigSource(homeDir.toPath()));
|
||||
|
||||
this.baseHome = new BaseHome(config);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCoordinate_NotMaven()
|
||||
{
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer(baseHome);
|
||||
String ref = "http://www.eclipse.org/jetty";
|
||||
Coordinates coords = repo.getCoordinates(URI.create(ref));
|
||||
assertThat("Coords",coords,nullValue());
|
||||
|
@ -45,7 +70,7 @@ public class MavenLocalRepoFileInitializerTest
|
|||
@Test
|
||||
public void testGetCoordinate_InvalidMaven()
|
||||
{
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer(baseHome);
|
||||
String ref = "maven://www.eclipse.org/jetty";
|
||||
expectedException.expect(RuntimeException.class);
|
||||
expectedException.expectMessage(containsString("Not a valid maven:// uri"));
|
||||
|
@ -55,7 +80,7 @@ public class MavenLocalRepoFileInitializerTest
|
|||
@Test
|
||||
public void testGetCoordinate_Normal()
|
||||
{
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer(baseHome);
|
||||
String ref = "maven://org.eclipse.jetty/jetty-start/9.3.x";
|
||||
Coordinates coords = repo.getCoordinates(URI.create(ref));
|
||||
assertThat("Coordinates",coords,notNullValue());
|
||||
|
@ -73,7 +98,7 @@ public class MavenLocalRepoFileInitializerTest
|
|||
@Test
|
||||
public void testGetCoordinate_Zip()
|
||||
{
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer(baseHome);
|
||||
String ref = "maven://org.eclipse.jetty/jetty-distribution/9.3.x/zip";
|
||||
Coordinates coords = repo.getCoordinates(URI.create(ref));
|
||||
assertThat("Coordinates",coords,notNullValue());
|
||||
|
@ -91,7 +116,7 @@ public class MavenLocalRepoFileInitializerTest
|
|||
@Test
|
||||
public void testGetCoordinate_TestJar()
|
||||
{
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer(baseHome);
|
||||
String ref = "maven://org.eclipse.jetty/jetty-http/9.3.x/jar/tests";
|
||||
Coordinates coords = repo.getCoordinates(URI.create(ref));
|
||||
assertThat("Coordinates",coords,notNullValue());
|
||||
|
@ -109,7 +134,7 @@ public class MavenLocalRepoFileInitializerTest
|
|||
@Test
|
||||
public void testGetCoordinate_Test_UnspecifiedType()
|
||||
{
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
|
||||
MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer(baseHome);
|
||||
String ref = "maven://org.eclipse.jetty/jetty-http/9.3.x//tests";
|
||||
Coordinates coords = repo.getCoordinates(URI.create(ref));
|
||||
assertThat("Coordinates",coords,notNullValue());
|
||||
|
|
Loading…
Reference in New Issue