* Support root base or home for quickstart #2446 Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #2446 - Root as base for quickstart + Adding more tests for differences we have to resolve with windows vs linux root path differences. and URI's that have an authority vs those without an authority. without authority examples: file:/code/ file:/C:/code/ with authority examples: file:///code/ file:///C:/code/ Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com> * Using the canonical URI passes all the tests on linux, but I still have some concerns with the whole approach Signed-off-by: Greg Wilkins <gregw@webtide.com> * minor cleanups Signed-off-by: Greg Wilkins <gregw@webtide.com> * Handle windows URIs Because a windows like `file:///F:/` has a path of `/F:/`, then it is OK to strip the trailing `/`, so the expected normalized value can be `file:///F:`. Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
5515e13649
commit
e59d6fa2c0
|
@ -78,14 +78,15 @@ public class AttributeNormalizer
|
|||
}
|
||||
}
|
||||
|
||||
private static URI toCanonicalURI(URI uri)
|
||||
public static URI toCanonicalURI(URI uri)
|
||||
{
|
||||
uri = uri.normalize();
|
||||
String ascii = uri.toASCIIString();
|
||||
if (ascii.endsWith("/"))
|
||||
String path = uri.getPath();
|
||||
if (path!=null && path.length()>1 && path.endsWith("/"))
|
||||
{
|
||||
try
|
||||
{
|
||||
String ascii = uri.toASCIIString();
|
||||
uri = new URI(ascii.substring(0,ascii.length()-1));
|
||||
}
|
||||
catch(URISyntaxException e)
|
||||
|
@ -96,7 +97,16 @@ public class AttributeNormalizer
|
|||
return uri;
|
||||
}
|
||||
|
||||
private static Path toCanonicalPath(String path)
|
||||
public static String toCanonicalURI(String uri)
|
||||
{
|
||||
if (uri!=null && uri.length()>1 && uri.endsWith("/"))
|
||||
{
|
||||
return uri.substring(0,uri.length()-1);
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
public static Path toCanonicalPath(String path)
|
||||
{
|
||||
if (path == null)
|
||||
return null;
|
||||
|
@ -148,8 +158,8 @@ public class AttributeNormalizer
|
|||
|
||||
public URIAttribute(String key, URI uri, int weight)
|
||||
{
|
||||
super(key,uri.toASCIIString(),weight);
|
||||
this.uri = uri;
|
||||
super(key,toCanonicalURI(uri.toASCIIString()),weight);
|
||||
this.uri = toCanonicalURI(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -198,17 +208,6 @@ public class AttributeNormalizer
|
|||
}
|
||||
};
|
||||
|
||||
private static void add(List<PathAttribute>paths,List<URIAttribute> uris,String key,int weight)
|
||||
{
|
||||
String value = System.getProperty(key);
|
||||
if (value!=null)
|
||||
{
|
||||
Path path = toCanonicalPath(value);
|
||||
paths.add(new PathAttribute(key,path,weight));
|
||||
uris.add(new URIAttribute(key+".uri",toCanonicalURI(path.toUri()),weight));
|
||||
}
|
||||
}
|
||||
|
||||
private URI warURI;
|
||||
private Map<String,Attribute> attributes = new HashMap<>();
|
||||
private List<PathAttribute> paths = new ArrayList<>();
|
||||
|
@ -223,10 +222,10 @@ public class AttributeNormalizer
|
|||
if (!warURI.isAbsolute())
|
||||
throw new IllegalArgumentException("WAR URI is not absolute: " + warURI);
|
||||
|
||||
add(paths,uris,"jetty.base",9);
|
||||
add(paths,uris,"jetty.home",8);
|
||||
add(paths,uris,"user.home",7);
|
||||
add(paths,uris,"user.dir",6);
|
||||
addSystemProperty("jetty.base", 9);
|
||||
addSystemProperty("jetty.home", 8);
|
||||
addSystemProperty("user.home", 7);
|
||||
addSystemProperty("user.dir", 6);
|
||||
|
||||
if (warURI.getScheme().equalsIgnoreCase("file"))
|
||||
paths.add(new PathAttribute("WAR.path",toCanonicalPath(new File(warURI).toString()),10));
|
||||
|
@ -247,6 +246,17 @@ public class AttributeNormalizer
|
|||
}
|
||||
}
|
||||
|
||||
private void addSystemProperty(String key, int weight)
|
||||
{
|
||||
String value = System.getProperty(key);
|
||||
if (value!=null)
|
||||
{
|
||||
Path path = toCanonicalPath(value);
|
||||
paths.add(new PathAttribute(key,path,weight));
|
||||
uris.add(new URIAttribute(key+".uri",path.toUri(),weight));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a URI, URL, or File reference by replacing known attributes with ${key} attributes.
|
||||
*
|
||||
|
@ -323,8 +333,6 @@ public class AttributeNormalizer
|
|||
protected String normalizeUri(URI uri)
|
||||
{
|
||||
for (URIAttribute a : uris)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (uri.compareTo(a.uri)==0)
|
||||
return String.format("${%s}",a.key);
|
||||
|
@ -336,23 +344,23 @@ public class AttributeNormalizer
|
|||
if (a.uri.getHost()!=null && !a.uri.getHost().equals(uri.getHost()))
|
||||
continue;
|
||||
|
||||
if (a.uri.getPath().equals(uri.getPath()))
|
||||
String aPath = a.uri.getPath();
|
||||
String uPath = uri.getPath();
|
||||
if (aPath.equals(uPath))
|
||||
return a.value;
|
||||
|
||||
if (!uri.getPath().startsWith(a.uri.getPath()))
|
||||
if (!uPath.startsWith(aPath))
|
||||
continue;
|
||||
|
||||
String s = uri.getPath().substring(a.uri.getPath().length());
|
||||
if (uPath.length()==aPath.length())
|
||||
return String.format("${%s}",a.key);
|
||||
|
||||
if (s.charAt(0)!='/')
|
||||
String s = uPath.substring(aPath.length());
|
||||
if (s.length()>0 && s.charAt(0)!='/')
|
||||
continue;
|
||||
|
||||
return String.format("${%s}%s",a.key,new URI(s).toASCIIString());
|
||||
}
|
||||
catch(URISyntaxException e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
return String.format("${%s}%s",a.key,s);
|
||||
|
||||
}
|
||||
return uri.toASCIIString();
|
||||
}
|
||||
|
|
|
@ -62,6 +62,16 @@ public class AttributeNormalizerTest
|
|||
|
||||
data.add(new Object[]{arch, title, env});
|
||||
|
||||
// ------
|
||||
title = "Old Setup";
|
||||
|
||||
env = new HashMap<>();
|
||||
env.put("jetty.home", asTargetPath(title,"jetty-distro"));
|
||||
env.put("jetty.base", asTargetPath(title,"jetty-distro"));
|
||||
env.put("WAR", asTargetPath(title,"jetty-distro/webapps/FOO"));
|
||||
|
||||
data.add(new Object[]{arch, title, env});
|
||||
|
||||
// ------
|
||||
// This puts the jetty.home inside of the jetty.base
|
||||
title = "Overlap Setup";
|
||||
|
@ -82,6 +92,17 @@ public class AttributeNormalizerTest
|
|||
env.put("WAR", asTargetPath(title,"app%2Fnasty/base/webapps/FOO"));
|
||||
|
||||
data.add(new Object[]{arch, title, env});
|
||||
|
||||
// ------
|
||||
title = "Root Path Setup";
|
||||
env = new HashMap<>();
|
||||
Path rootPath = MavenTestingUtils.getTargetPath().getRoot();
|
||||
env.put("jetty.home", rootPath.toString());
|
||||
env.put("jetty.base", rootPath.toString());
|
||||
env.put("WAR", rootPath.resolve("webapps/root").toString());
|
||||
|
||||
data.add(new Object[]{arch, title, env});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -96,8 +117,8 @@ public class AttributeNormalizerTest
|
|||
}
|
||||
|
||||
private Map<String, String> oldValues = new HashMap<>();
|
||||
private final String jettyHome;
|
||||
private final String jettyBase;
|
||||
private final Path jettyHome;
|
||||
private final Path jettyBase;
|
||||
private final String war;
|
||||
private final String arch;
|
||||
private final String title;
|
||||
|
@ -118,8 +139,8 @@ public class AttributeNormalizerTest
|
|||
});
|
||||
|
||||
// Grab specific values of interest in general
|
||||
jettyHome = env.get("jetty.home");
|
||||
jettyBase = env.get("jetty.base");
|
||||
jettyHome = new File(env.get("jetty.home")).toPath().toAbsolutePath();
|
||||
jettyBase = new File(env.get("jetty.base")).toPath().toAbsolutePath();
|
||||
war = env.get("WAR");
|
||||
|
||||
// Set environment (skipping null and WAR)
|
||||
|
@ -176,42 +197,79 @@ public class AttributeNormalizerTest
|
|||
public void testNormalizeJettyBaseAsFile()
|
||||
{
|
||||
// Normalize jetty.base as File path
|
||||
assertNormalize(new File(jettyBase), "${jetty.base}");
|
||||
assertNormalize(jettyBase.toFile(), "${jetty.base}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeJettyHomeAsFile()
|
||||
{
|
||||
// Normalize jetty.home as File path
|
||||
assertNormalize(new File(jettyHome), "${jetty.home}");
|
||||
String expected = jettyBase.equals(jettyHome)?"${jetty.base}":"${jetty.home}";
|
||||
assertNormalize(jettyHome.toFile(), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeJettyBaseAsURI()
|
||||
public void testNormalizeJettyBaseAsPath()
|
||||
{
|
||||
// Normalize jetty.base as File path
|
||||
assertNormalize(jettyBase, "${jetty.base}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeJettyHomeAsPath()
|
||||
{
|
||||
// Normalize jetty.home as File path
|
||||
String expected = jettyBase.equals(jettyHome)?"${jetty.base}":"${jetty.home}";
|
||||
assertNormalize(jettyHome, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeJettyBaseAsURI_WithAuthority()
|
||||
{
|
||||
// Normalize jetty.base as URI path
|
||||
assertNormalize(new File(jettyBase).toURI(), "${jetty.base.uri}");
|
||||
// Path.toUri() typically includes an URI authority
|
||||
assertNormalize(jettyBase.toUri(), "${jetty.base.uri}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeJettyHomeAsURI()
|
||||
public void testNormalizeJettyBaseAsURI_WithoutAuthority()
|
||||
{
|
||||
// Normalize jetty.base as URI path
|
||||
// File.toURI() typically DOES NOT include an URI authority
|
||||
assertNormalize(jettyBase.toFile().toURI(), "${jetty.base.uri}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeJettyHomeAsURI_WithAuthority()
|
||||
{
|
||||
// Normalize jetty.home as URI path
|
||||
assertNormalize(new File(jettyHome).toURI(), "${jetty.home.uri}");
|
||||
String expected = jettyBase.equals(jettyHome)?"${jetty.base.uri}":"${jetty.home.uri}";
|
||||
|
||||
// Path.toUri() typically includes an URI authority
|
||||
assertNormalize(jettyHome.toUri(), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalizeJettyHomeAsURI_WithoutAuthority()
|
||||
{
|
||||
// Normalize jetty.home as URI path
|
||||
String expected = jettyBase.equals(jettyHome)?"${jetty.base.uri}":"${jetty.home.uri}";
|
||||
// File.toURI() typically DOES NOT include an URI authority
|
||||
assertNormalize(jettyHome.toFile().toURI(), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandJettyBase()
|
||||
{
|
||||
// Expand jetty.base
|
||||
assertExpandPath("${jetty.base}", jettyBase);
|
||||
assertExpandPath("${jetty.base}", jettyBase.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandJettyHome()
|
||||
{
|
||||
// Expand jetty.home
|
||||
assertExpandPath("${jetty.home}", jettyHome);
|
||||
assertExpandPath("${jetty.home}", jettyHome.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.quickstart;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class AttributeNormalizer_ToCanonicalUriTest
|
||||
{
|
||||
@Parameterized.Parameters(name = "[{index}] {0} - {1}")
|
||||
public static List<Object[]> data()
|
||||
{
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
|
||||
|
||||
// root without authority
|
||||
data.add(new String[]{ "file:/", "file:/" });
|
||||
data.add(new String[]{ "file:/F:/", "file:/F:" });
|
||||
|
||||
// root with empty authority
|
||||
data.add(new String[]{ "file:///", "file:///" });
|
||||
data.add(new String[]{ "file:///F:/", "file:///F:" });
|
||||
|
||||
// deep directory - no authority
|
||||
data.add(new String[]{ "file:/home/user/code/", "file:/home/user/code" });
|
||||
data.add(new String[]{ "file:/C:/code/", "file:/C:/code" });
|
||||
|
||||
// deep directory - with authority
|
||||
data.add(new String[]{ "file:///home/user/code/", "file:///home/user/code" });
|
||||
data.add(new String[]{ "file:///C:/code/", "file:///C:/code" });
|
||||
|
||||
// Some non-file tests
|
||||
data.add(new String[]{ "http://webtide.com/", "http://webtide.com/" });
|
||||
data.add(new String[]{ "http://webtide.com/cometd/", "http://webtide.com/cometd" });
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Parameterized.Parameter
|
||||
public String input;
|
||||
|
||||
@Parameterized.Parameter(1)
|
||||
public String expected;
|
||||
|
||||
@Test
|
||||
public void testCanonicalURI()
|
||||
{
|
||||
URI inputURI = URI.create(input);
|
||||
URI actual = AttributeNormalizer.toCanonicalURI(inputURI);
|
||||
assertThat(input, actual.toASCIIString(), is(expected));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue