Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Erdfelt2014-11-13 21:23:26 +0000
committerJoakim Erdfelt2014-11-13 21:23:26 +0000
commit15bf5b02f8946c02901ba16a6dd9f02221013c69 (patch)
treea863801789bae8fa2c037e527a2f62bb79626178 /jetty-start
parenta308c087edae79917b40dbc8e1b5f0c0b3b15b12 (diff)
downloadorg.eclipse.jetty.project-15bf5b02f8946c02901ba16a6dd9f02221013c69.tar.gz
org.eclipse.jetty.project-15bf5b02f8946c02901ba16a6dd9f02221013c69.tar.xz
org.eclipse.jetty.project-15bf5b02f8946c02901ba16a6dd9f02221013c69.zip
Updating Main.initFiles() to be extensible
Diffstat (limited to 'jetty-start')
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/FileInitializer.java43
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/Main.java279
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java9
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/Utils.java72
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/config/CommandLineConfigSource.java27
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializer.java191
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/TestFileInitializer.java44
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/UriFileInitializer.java130
-rw-r--r--jetty-start/src/test/java/org/eclipse/jetty/start/LicenseTest.java1
-rw-r--r--jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java126
10 files changed, 783 insertions, 139 deletions
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/FileInitializer.java b/jetty-start/src/main/java/org/eclipse/jetty/start/FileInitializer.java
new file mode 100644
index 0000000000..905915cc4b
--- /dev/null
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/FileInitializer.java
@@ -0,0 +1,43 @@
+//
+// ========================================================================
+// 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.Path;
+
+/**
+ * Interface for initializing a file resource.
+ */
+public interface FileInitializer
+{
+ /**
+ * Initialize a file resource
+ *
+ * @param uri
+ * 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.
+ * @throws IOException
+ * if there was an attempt to initialize, but an error occurred.
+ */
+ public boolean init(URI uri, Path file) throws IOException;
+}
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 eca1f7929f..c0ffd6cb34 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
@@ -35,7 +35,7 @@ import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
-import java.net.URL;
+import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -50,6 +50,9 @@ 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.
@@ -172,76 +175,6 @@ public class Main
}).start();
}
- private void initFile(StartArgs args, FileArg farg)
- {
- try
- {
- Path file = baseHome.getBasePath(farg.location);
-
- StartLog.debug("[init-file] %s module specified file %s",file.toAbsolutePath(),(FS.exists(file)?"[Exists!]":""));
- if (FS.exists(file))
- {
- // file already initialized / downloaded, skip it
- return;
- }
-
- if (farg.uri!=null)
- {
- URL url = new URL(farg.uri);
-
- StartLog.log("DOWNLOAD", "%s to %s", url, farg.location);
-
- FS.ensureDirectoryExists(file.getParent());
-
- if (args.isTestingModeEnabled())
- {
- StartLog.log("TESTING MODE", "Skipping download of " + url);
- return;
- }
-
- byte[] buf = new byte[8192];
- try (InputStream in = url.openStream();
- OutputStream out = Files.newOutputStream(file,StandardOpenOption.CREATE_NEW,StandardOpenOption.WRITE))
- {
- while (true)
- {
- int len = in.read(buf);
-
- if (len > 0)
- {
- out.write(buf,0,len);
- }
- if (len < 0)
- {
- break;
- }
- }
- }
- }
- else if (farg.location.endsWith("/"))
- {
- StartLog.log("MKDIR",baseHome.toShortForm(file));
- FS.ensureDirectoryExists(file);
- }
- else
- {
- String shortRef = baseHome.toShortForm(file);
- if (args.isTestingModeEnabled())
- {
- StartLog.log("TESTING MODE","Skipping required file check on: %s",shortRef);
- return;
- }
- StartLog.warn("MISSING: Required file %s",shortRef);
- }
- }
- catch (Exception e)
- {
- StartLog.warn("ERROR: processing %s%n%s",farg,e);
- StartLog.warn(e);
- usageExit(EXIT_USAGE);
- }
- }
-
private void dumpClasspathWithVersions(Classpath classpath)
{
StartLog.endStartLog();
@@ -366,6 +299,7 @@ public class Main
* 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
@@ -373,7 +307,7 @@ public class Main
* false to create a <code>${jetty.base}/start.d/${name}.ini</code> entry instead.
* @throws IOException
*/
- private void buildIni(StartArgs args, String name, boolean topLevel, boolean appendStartIni) 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");
@@ -512,10 +446,12 @@ public class Main
}
// Do downloads now
+ List<FileArg> files = new ArrayList<FileArg>();
for (String file : module.getFiles())
{
- initFile(args, new FileArg(module,file));
+ files.add(new FileArg(module,file));
}
+ processFileResources(fileInitializers,args,files);
// Process dependencies
module.expandProperties(args.getProperties());
@@ -547,7 +483,7 @@ public class Main
if (!done.contains(m.getName()))
{
complete=false;
- buildIni(args,m.getName(),false,appendStartIni);
+ buildIni(fileInitializers,args,m.getName(),false,appendStartIni);
done.add(m.getName());
}
}
@@ -636,7 +572,140 @@ 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);
@@ -692,19 +761,33 @@ public class Main
doStop(args);
}
+ // Establish FileInitializers
+ List<FileInitializer> fileInitializers = new ArrayList<FileInitializer>();
+ if (args.isTestingModeEnabled())
+ {
+ // No downloads performed
+ fileInitializers.add(new TestFileInitializer());
+ }
+ else
+ {
+ // Downloads performed
+ fileInitializers.add(new MavenLocalRepoFileInitializer());
+ fileInitializers.add(new UriFileInitializer());
+ }
+
boolean rebuildGraph = false;
// Initialize start.ini
for (String module : args.getAddToStartIni())
{
- buildIni(args,module,true,true);
+ buildIni(fileInitializers,args,module,true,true);
rebuildGraph = true;
}
// Initialize start.d
for (String module : args.getAddToStartdIni())
{
- buildIni(args,module,true,false);
+ buildIni(fileInitializers,args,module,true,false);
rebuildGraph = true;
}
@@ -719,6 +802,7 @@ public class Main
{
if (!args.isApproveAllLicenses())
{
+ StartLog.debug("Requesting License Acknowledgement");
for (Module module : args.getAllModules().resolveEnabled())
{
if (!module.acknowledgeLicense())
@@ -730,46 +814,7 @@ public class Main
}
}
- // Check ini files for download possibilities
- for (FileArg arg : args.getFiles())
- {
- Path file = baseHome.getBasePath(arg.location);
- if (!FS.exists(file) && args.isDownload())
- {
- initFile(args, arg);
- }
-
- if (!FS.exists(file))
- {
- boolean isDir = arg.location.endsWith("/");
- if (isDir)
- {
- StartLog.log("MKDIR", baseHome.toShortForm(file));
- FS.ensureDirectoryExists(file);
- /* Startup should not fail to run on missing directories.
- * See Bug #427204
- */
- // args.setRun(false);
- }
- else
- {
- String shortRef = baseHome.toShortForm(file);
- if (args.isTestingModeEnabled())
- {
- StartLog.log("TESTING MODE","Skipping required file check on: %s",shortRef);
- return;
- }
-
- 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");
- }
- }
- }
- }
+ processFileResources(fileInitializers, args);
// Informational command line, don't run jetty
if (!args.isRun())
@@ -822,6 +867,8 @@ public class Main
}
}
+
+
private void doStop(StartArgs args)
{
int stopPort = Integer.parseInt(args.getProperties().getString("STOP.PORT"));
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
index 8f553f8682..2077f2d677 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
@@ -112,7 +112,11 @@ public class StartArgs
private Modules allModules;
/** Should the server be run? */
private boolean run = true;
+
+ /** Download related args */
private boolean download = false;
+ private boolean testingMode = false;
+
private boolean help = false;
private boolean stopCommand = false;
private boolean listModules = false;
@@ -123,7 +127,6 @@ public class StartArgs
private boolean exec = false;
private boolean approveAllLicenses = false;
- private boolean testingMode = false;
public StartArgs()
{
@@ -135,6 +138,10 @@ public class StartArgs
FileArg arg = new FileArg(module, uriLocation);
if (!files.contains(arg))
{
+ if (arg.uri != null)
+ {
+ this.download = true;
+ }
files.add(arg);
}
}
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Utils.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Utils.java
new file mode 100644
index 0000000000..3e7ffa80b7
--- /dev/null
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Utils.java
@@ -0,0 +1,72 @@
+//
+// ========================================================================
+// 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;
+
+public final class Utils
+{
+ /**
+ * Is String null, empty, or consisting of only whitespace.
+ *
+ * @param value
+ * the value to test
+ * @return true if null, empty, or consisting of only whitespace
+ */
+ public static boolean isBlank(String value)
+ {
+ if (value == null)
+ {
+ return true;
+ }
+ int len = value.length();
+ for (int i = 0; i < len; i++)
+ {
+ int c = value.codePointAt(i);
+ if (!Character.isWhitespace(c))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Is String valid and has something other than whitespace
+ *
+ * @param value
+ * the value to test
+ * @return true if String has something other than whitespace
+ */
+ public static boolean isNotBlank(String value)
+ {
+ if (value == null)
+ {
+ return false;
+ }
+ int len = value.length();
+ for (int i = 0; i < len; i++)
+ {
+ int c = value.codePointAt(i);
+ if (!Character.isWhitespace(c))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/config/CommandLineConfigSource.java b/jetty-start/src/main/java/org/eclipse/jetty/start/config/CommandLineConfigSource.java
index 934158f1ac..af3c54fa9d 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/config/CommandLineConfigSource.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/config/CommandLineConfigSource.java
@@ -32,6 +32,7 @@ import org.eclipse.jetty.start.Props;
import org.eclipse.jetty.start.Props.Prop;
import org.eclipse.jetty.start.RawArgs;
import org.eclipse.jetty.start.UsageException;
+import org.eclipse.jetty.start.Utils;
/**
* Configuration Source representing the Command Line arguments.
@@ -69,14 +70,14 @@ public class CommandLineConfigSource implements ConfigSource
{
// If a jetty property is defined, use it
Prop prop = this.props.getProp(BaseHome.JETTY_BASE,false);
- if (prop != null && !isEmpty(prop.value))
+ if (prop != null && !Utils.isBlank(prop.value))
{
return FS.toPath(prop.value);
}
// If a system property is defined, use it
String val = System.getProperty(BaseHome.JETTY_BASE);
- if (!isEmpty(val))
+ if (!Utils.isBlank(val))
{
return FS.toPath(val);
}
@@ -91,14 +92,14 @@ public class CommandLineConfigSource implements ConfigSource
{
// If a jetty property is defined, use it
Prop prop = this.props.getProp(BaseHome.JETTY_HOME,false);
- if (prop != null && !isEmpty(prop.value))
+ if (prop != null && !Utils.isBlank(prop.value))
{
return FS.toPath(prop.value);
}
// If a system property is defined, use it
String val = System.getProperty(BaseHome.JETTY_HOME);
- if (!isEmpty(val))
+ if (!Utils.isBlank(val))
{
return FS.toPath(val);
}
@@ -130,24 +131,6 @@ public class CommandLineConfigSource implements ConfigSource
return home;
}
- private boolean isEmpty(String value)
- {
- if (value == null)
- {
- return true;
- }
- int len = value.length();
- for (int i = 0; i < len; i++)
- {
- int c = value.codePointAt(i);
- if (!Character.isWhitespace(c))
- {
- return false;
- }
- }
- return true;
- }
-
@Override
public boolean equals(Object obj)
{
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializer.java b/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializer.java
new file mode 100644
index 0000000000..6aca80597e
--- /dev/null
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializer.java
@@ -0,0 +1,191 @@
+//
+// ========================================================================
+// 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.fileinits;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.jetty.start.FS;
+import org.eclipse.jetty.start.FileInitializer;
+import org.eclipse.jetty.start.StartLog;
+import org.eclipse.jetty.start.Utils;
+
+/**
+ * Attempt to download a <code>maven://</code> URI, by first attempting to find
+ * the resource in the maven repository system (starting with local, then
+ * central)
+ * <p>
+ * Valid URI Formats:
+ * <dl>
+ * <dt><code>maven://&lt;groupId>/&lt;artifactId>/&lt;version></code></dt>
+ * <dd>minimum requirement (type defaults to <code>jar</code>, with no
+ * classifier)</dd>
+ * <dt><code>maven://&lt;groupId>/&lt;artifactId>/&lt;version>/&lt;type></code></dt>
+ * <dd>optional type requirement</dd>
+ * <dt>
+ * <code>maven://&lt;groupId>/&lt;artifactId>/&lt;version>/&lt;type>/&lt;classifier></code>
+ * </dt>
+ * <dd>optional type and classifier requirement</dd>
+ * </dl>
+ */
+public class MavenLocalRepoFileInitializer extends UriFileInitializer implements FileInitializer
+{
+ public static class Coordinates
+ {
+ public String groupId;
+ public String artifactId;
+ public String version;
+ public String type;
+ public String classifier;
+
+ public String toPath()
+ {
+ StringBuilder pathlike = new StringBuilder();
+ pathlike.append(groupId.replace('.','/'));
+ pathlike.append('/').append(artifactId);
+ pathlike.append('/').append(version);
+ pathlike.append('/').append(artifactId);
+ pathlike.append('-').append(version);
+ if (classifier != null)
+ {
+ pathlike.append('-').append(classifier);
+ }
+ pathlike.append('.').append(type);
+ return pathlike.toString();
+ }
+
+ public URI toCentralURI()
+ {
+ return URI.create("http://central.maven.org/maven2/" + toPath());
+ }
+ }
+
+ private Path localRepositoryDir;
+
+ public MavenLocalRepoFileInitializer()
+ {
+ this(null);
+ }
+
+ public MavenLocalRepoFileInitializer(Path localRepoDir)
+ {
+ this.localRepositoryDir = localRepoDir;
+ }
+
+ @Override
+ public boolean init(URI uri, Path file) throws IOException
+ {
+ Coordinates coords = getCoordinates(uri);
+ if (coords == null)
+ {
+ // Skip, not a maven:// URI
+ return false;
+ }
+
+ if (isFilePresent(file))
+ {
+ // All done
+ return true;
+ }
+
+ // If using local repository
+ if (this.localRepositoryDir != null)
+ {
+ // Grab copy from local repository (download if needed to local
+ // repository)
+ Path localRepoFile = getLocalRepoFile(coords);
+ Files.copy(localRepoFile,file);
+ }
+ else
+ {
+ // normal non-local repo version
+ download(coords.toCentralURI(),file);
+ }
+ return true;
+ }
+
+ private Path getLocalRepoFile(Coordinates coords) throws IOException
+ {
+ Path localFile = localRepositoryDir.resolve(coords.toPath());
+ if (FS.canReadFile(localFile))
+ {
+ return localFile;
+ }
+
+ // Download, if needed
+ download(coords.toCentralURI(),localFile);
+ return localFile;
+ }
+
+ public Coordinates getCoordinates(URI uri)
+ {
+ if (!"maven".equalsIgnoreCase(uri.getScheme()))
+ {
+ return null;
+ }
+
+ String ssp = uri.getSchemeSpecificPart();
+
+ if (ssp.startsWith("//"))
+ {
+ ssp = ssp.substring(2);
+ }
+
+ String parts[] = ssp.split("/");
+
+ if (StartLog.isDebugEnabled())
+ {
+ StartLog.debug("ssp = %s",ssp);
+ StartLog.debug("parts = %d",parts.length);
+ for (int i = 0; i < parts.length; i++)
+ {
+ StartLog.debug(" part[%2d]: [%s]",i,parts[i]);
+ }
+ }
+
+ if (parts.length < 3)
+ {
+ throw new RuntimeException("Not a valid maven:// uri - " + uri);
+ }
+
+ Coordinates coords = new Coordinates();
+ coords.groupId = parts[0];
+ coords.artifactId = parts[1];
+ coords.version = parts[2];
+ coords.type = "jar";
+ coords.classifier = null;
+
+ if (parts.length >= 4)
+ {
+ if (Utils.isNotBlank(parts[3]))
+ {
+ coords.type = parts[3];
+ }
+
+ if ((parts.length == 5) && (Utils.isNotBlank(parts[4])))
+ {
+ coords.classifier = parts[4];
+ }
+ }
+
+ return coords;
+ }
+}
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/TestFileInitializer.java b/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/TestFileInitializer.java
new file mode 100644
index 0000000000..dc9fd474be
--- /dev/null
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/TestFileInitializer.java
@@ -0,0 +1,44 @@
+//
+// ========================================================================
+// 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.fileinits;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Path;
+
+import org.eclipse.jetty.start.FS;
+import org.eclipse.jetty.start.FileInitializer;
+import org.eclipse.jetty.start.StartLog;
+
+/**
+ * In a start testing scenario, it is often not important to actually download
+ * or initialize a file, this implementation is merely a no-op for the
+ * {@link FileInitializer}
+ */
+public class TestFileInitializer implements FileInitializer
+{
+ @Override
+ public boolean init(URI uri, Path file) throws IOException
+ {
+ FS.ensureDirectoryExists(file.getParent());
+
+ StartLog.log("TESTING MODE","Skipping download of " + uri);
+ return true;
+ }
+}
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/UriFileInitializer.java b/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/UriFileInitializer.java
new file mode 100644
index 0000000000..785e40ec70
--- /dev/null
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/UriFileInitializer.java
@@ -0,0 +1,130 @@
+//
+// ========================================================================
+// 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.fileinits;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+
+import org.eclipse.jetty.start.FS;
+import org.eclipse.jetty.start.FileInitializer;
+import org.eclipse.jetty.start.StartLog;
+
+public class UriFileInitializer implements FileInitializer
+{
+ private final static String[] SUPPORTED_SCHEMES = { "http", "https" };
+
+ @Override
+ public boolean init(URI uri, Path file) throws IOException
+ {
+ if (!isSupportedScheme(uri))
+ {
+ // Not a supported scheme.
+ return false;
+ }
+
+ if(isFilePresent(file))
+ {
+ // All done
+ return true;
+ }
+
+ download(uri,file);
+
+ return true;
+ }
+
+ protected void download(URI uri, Path file) throws IOException
+ {
+ StartLog.log("DOWNLOAD","%s to %s",uri,file);
+
+ FS.ensureDirectoryExists(file.getParent());
+
+ HttpURLConnection http = (HttpURLConnection)uri.toURL().openConnection();
+ http.setInstanceFollowRedirects(true);
+ http.setAllowUserInteraction(false);
+
+ int status = http.getResponseCode();
+
+ if(status != HttpURLConnection.HTTP_OK)
+ {
+ throw new IOException("URL GET Failure [" + status + "/" + http.getResponseMessage() + "] on " + uri);
+ }
+
+ byte[] buf = new byte[8192];
+ try (InputStream in = http.getInputStream(); OutputStream out = Files.newOutputStream(file,StandardOpenOption.CREATE_NEW,StandardOpenOption.WRITE))
+ {
+ while (true)
+ {
+ int len = in.read(buf);
+
+ if (len > 0)
+ {
+ out.write(buf,0,len);
+ }
+ if (len < 0)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ protected boolean isFilePresent(Path file) throws IOException
+ {
+ if (Files.exists(file))
+ {
+ if (Files.isDirectory(file))
+ {
+ throw new IOException("Directory in the way: " + file.toAbsolutePath());
+ }
+
+ if (Files.isReadable(file))
+ {
+ throw new IOException("File not readable: " + file.toAbsolutePath());
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isSupportedScheme(URI uri)
+ {
+ String scheme = uri.getScheme();
+ if (scheme == null)
+ {
+ return false;
+ }
+ for (String supported : SUPPORTED_SCHEMES)
+ {
+ if (supported.equalsIgnoreCase(scheme))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/LicenseTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/LicenseTest.java
index c6d040fa64..a7a7ebdd9f 100644
--- a/jetty-start/src/test/java/org/eclipse/jetty/start/LicenseTest.java
+++ b/jetty-start/src/test/java/org/eclipse/jetty/start/LicenseTest.java
@@ -123,6 +123,7 @@ public class LicenseTest
List<String> cmds = getBaseCommandLine(basePath);
cmds.add("-Dorg.eclipse.jetty.start.ack.license.protonego-impl=true");
+ cmds.add("--dry-run");
StringReader startIni = new StringReader("--module=spdy\n");
try (FileWriter writer = new FileWriter(new File(basePath,"start.ini")))
diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java
new file mode 100644
index 0000000000..871eb6d6fc
--- /dev/null
+++ b/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java
@@ -0,0 +1,126 @@
+//
+// ========================================================================
+// 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.fileinits;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.net.URI;
+
+import org.eclipse.jetty.start.fileinits.MavenLocalRepoFileInitializer.Coordinates;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class MavenLocalRepoFileInitializerTest
+{
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void testGetCoordinate_NotMaven()
+ {
+ MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
+ String ref = "http://www.eclipse.org/jetty";
+ Coordinates coords = repo.getCoordinates(URI.create(ref));
+ assertThat("Coords",coords,nullValue());
+ }
+
+ @Test
+ public void testGetCoordinate_InvalidMaven()
+ {
+ MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
+ String ref = "maven://www.eclipse.org/jetty";
+ expectedException.expect(RuntimeException.class);
+ expectedException.expectMessage(containsString("Not a valid maven:// uri"));
+ repo.getCoordinates(URI.create(ref));
+ }
+
+ @Test
+ public void testGetCoordinate_Normal()
+ {
+ MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
+ String ref = "maven://org.eclipse.jetty/jetty-start/9.3.x";
+ Coordinates coords = repo.getCoordinates(URI.create(ref));
+ assertThat("Coordinates",coords,notNullValue());
+
+ assertThat("coords.groupId",coords.groupId,is("org.eclipse.jetty"));
+ assertThat("coords.artifactId",coords.artifactId,is("jetty-start"));
+ assertThat("coords.version",coords.version,is("9.3.x"));
+ assertThat("coords.type",coords.type,is("jar"));
+ assertThat("coords.classifier",coords.classifier,nullValue());
+
+ assertThat("coords.toCentralURI", coords.toCentralURI().toASCIIString(),
+ is("http://central.maven.org/maven2/org/eclipse/jetty/jetty-start/9.3.x/jetty-start-9.3.x.jar"));
+ }
+
+ @Test
+ public void testGetCoordinate_Zip()
+ {
+ MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
+ String ref = "maven://org.eclipse.jetty/jetty-distribution/9.3.x/zip";
+ Coordinates coords = repo.getCoordinates(URI.create(ref));
+ assertThat("Coordinates",coords,notNullValue());
+
+ assertThat("coords.groupId",coords.groupId,is("org.eclipse.jetty"));
+ assertThat("coords.artifactId",coords.artifactId,is("jetty-distribution"));
+ assertThat("coords.version",coords.version,is("9.3.x"));
+ assertThat("coords.type",coords.type,is("zip"));
+ assertThat("coords.classifier",coords.classifier,nullValue());
+
+ assertThat("coords.toCentralURI", coords.toCentralURI().toASCIIString(),
+ is("http://central.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.3.x/jetty-distribution-9.3.x.zip"));
+ }
+
+ @Test
+ public void testGetCoordinate_TestJar()
+ {
+ MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
+ String ref = "maven://org.eclipse.jetty/jetty-http/9.3.x/jar/tests";
+ Coordinates coords = repo.getCoordinates(URI.create(ref));
+ assertThat("Coordinates",coords,notNullValue());
+
+ assertThat("coords.groupId",coords.groupId,is("org.eclipse.jetty"));
+ assertThat("coords.artifactId",coords.artifactId,is("jetty-http"));
+ assertThat("coords.version",coords.version,is("9.3.x"));
+ assertThat("coords.type",coords.type,is("jar"));
+ assertThat("coords.classifier",coords.classifier,is("tests"));
+
+ assertThat("coords.toCentralURI", coords.toCentralURI().toASCIIString(),
+ is("http://central.maven.org/maven2/org/eclipse/jetty/jetty-http/9.3.x/jetty-http-9.3.x-tests.jar"));
+ }
+
+ @Test
+ public void testGetCoordinate_Test_UnspecifiedType()
+ {
+ MavenLocalRepoFileInitializer repo = new MavenLocalRepoFileInitializer();
+ String ref = "maven://org.eclipse.jetty/jetty-http/9.3.x//tests";
+ Coordinates coords = repo.getCoordinates(URI.create(ref));
+ assertThat("Coordinates",coords,notNullValue());
+
+ assertThat("coords.groupId",coords.groupId,is("org.eclipse.jetty"));
+ assertThat("coords.artifactId",coords.artifactId,is("jetty-http"));
+ assertThat("coords.version",coords.version,is("9.3.x"));
+ assertThat("coords.type",coords.type,is("jar"));
+ assertThat("coords.classifier",coords.classifier,is("tests"));
+
+ assertThat("coords.toCentralURI", coords.toCentralURI().toASCIIString(),
+ is("http://central.maven.org/maven2/org/eclipse/jetty/jetty-http/9.3.x/jetty-http-9.3.x-tests.jar"));
+ }
+}

Back to the top