remove default domain, stricter security
This commit is contained in:
parent
4fc4e72cb2
commit
abd1df903b
16 changed files with 161 additions and 127 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib
|
group = org.xbib
|
||||||
name = net
|
name = net
|
||||||
version = 3.2.0
|
version = 3.3.0
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class PathDecoder {
|
||||||
String path = pos > 0 ? pathAndQuery.substring(0, pos) : pathAndQuery;
|
String path = pos > 0 ? pathAndQuery.substring(0, pos) : pathAndQuery;
|
||||||
this.query = pos > 0 ? pathAndQuery.substring(pos + 1) : null;
|
this.query = pos > 0 ? pathAndQuery.substring(pos + 1) : null;
|
||||||
this.path = PathNormalizer.normalize(path);
|
this.path = PathNormalizer.normalize(path);
|
||||||
this.params = Parameter.builder().enablePercentDecoding();
|
this.params = Parameter.builder().domain(Parameter.Domain.PATH).enablePercentDecoding();
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
parse(query);
|
parse(query);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package org.xbib.net.path;
|
package org.xbib.net.path;
|
||||||
|
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
|
import org.xbib.net.ParameterException;
|
||||||
|
|
||||||
public interface PathResolver<T> {
|
public interface PathResolver<T> {
|
||||||
|
|
||||||
void resolve(String method, String path, ResultListener<T> listener);
|
void resolve(String method, String path, ResultListener<T> listener) throws ParameterException;
|
||||||
|
|
||||||
interface Builder<T> {
|
interface Builder<T> {
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ public interface PathResolver<T> {
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
interface ResultListener<T> {
|
interface ResultListener<T> {
|
||||||
|
|
||||||
void onResult(Result<T> result);
|
void onResult(Result<T> result) throws ParameterException;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,11 +50,11 @@ public class PathMatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Parameter extractUriTemplateVariables(String pattern, String path) {
|
public Parameter extractUriTemplateVariables(String pattern, String path) {
|
||||||
ParameterBuilder queryParameters = Parameter.builder();
|
ParameterBuilder uriParameters = Parameter.builder().domain(Parameter.Domain.PATH);
|
||||||
if (!doMatch(pattern, path, true, queryParameters)) {
|
if (!doMatch(pattern, path, true, uriParameters)) {
|
||||||
throw new IllegalStateException("Pattern \"" + pattern + "\" is not a match for \"" + path + "\"");
|
throw new IllegalStateException("Pattern \"" + pattern + "\" is not a match for \"" + path + "\"");
|
||||||
}
|
}
|
||||||
return queryParameters.build();
|
return uriParameters.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathComparator getPatternComparator(String path) {
|
public PathComparator getPatternComparator(String path) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.xbib.net.path.simple;
|
||||||
|
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
import org.xbib.net.ParameterBuilder;
|
import org.xbib.net.ParameterBuilder;
|
||||||
|
import org.xbib.net.ParameterException;
|
||||||
import org.xbib.net.util.CharMatcher;
|
import org.xbib.net.util.CharMatcher;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -53,7 +54,7 @@ public class PathResolver<T> implements org.xbib.net.path.PathResolver<T> {
|
||||||
* @param resultListener result listener
|
* @param resultListener result listener
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void resolve(String method, String path, ResultListener<T> resultListener) {
|
public void resolve(String method, String path, ResultListener<T> resultListener) throws ParameterException {
|
||||||
Objects.requireNonNull(method, "method");
|
Objects.requireNonNull(method, "method");
|
||||||
Objects.requireNonNull(path, "path");
|
Objects.requireNonNull(path, "path");
|
||||||
resolve(method, builder.pathMatcher.tokenize(path), 0, new ArrayList<>(), resultListener);
|
resolve(method, builder.pathMatcher.tokenize(path), 0, new ArrayList<>(), resultListener);
|
||||||
|
@ -68,7 +69,7 @@ public class PathResolver<T> implements org.xbib.net.path.PathResolver<T> {
|
||||||
List<String> pathSegments,
|
List<String> pathSegments,
|
||||||
int index,
|
int index,
|
||||||
List<String> parameters,
|
List<String> parameters,
|
||||||
ResultListener<T> resultListener) {
|
ResultListener<T> resultListener) throws ParameterException {
|
||||||
if (index < pathSegments.size()) {
|
if (index < pathSegments.size()) {
|
||||||
String segment = pathSegments.get(index);
|
String segment = pathSegments.get(index);
|
||||||
PathResolver<T> child = children.get(segment);
|
PathResolver<T> child = children.get(segment);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
import org.xbib.net.ParameterBuilder;
|
import org.xbib.net.ParameterBuilder;
|
||||||
|
import org.xbib.net.ParameterException;
|
||||||
import org.xbib.net.PathNormalizer;
|
import org.xbib.net.PathNormalizer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -37,7 +38,7 @@ public class PathResolver<T> implements org.xbib.net.path.PathResolver<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resolve(String method, String path, ResultListener<T> listener) {
|
public void resolve(String method, String path, ResultListener<T> listener) throws ParameterException {
|
||||||
Objects.requireNonNull(method, "method");
|
Objects.requireNonNull(method, "method");
|
||||||
Objects.requireNonNull(path, "path");
|
Objects.requireNonNull(path, "path");
|
||||||
List<PathSegment> pathSegments = PathMatcher.tokenize(PathNormalizer.normalize(path),
|
List<PathSegment> pathSegments = PathMatcher.tokenize(PathNormalizer.normalize(path),
|
||||||
|
@ -54,7 +55,7 @@ public class PathResolver<T> implements org.xbib.net.path.PathResolver<T> {
|
||||||
private ParameterBuilder resolve(List<PathSegment> pathSegments,
|
private ParameterBuilder resolve(List<PathSegment> pathSegments,
|
||||||
int index,
|
int index,
|
||||||
ParameterBuilder parameterBuilder,
|
ParameterBuilder parameterBuilder,
|
||||||
ResultListener<T> listener) {
|
ResultListener<T> listener) throws ParameterException {
|
||||||
ParameterBuilder pb = parameterBuilder;
|
ParameterBuilder pb = parameterBuilder;
|
||||||
if (index < pathSegments.size()) {
|
if (index < pathSegments.size()) {
|
||||||
PathSegment segment = pathSegments.get(index);
|
PathSegment segment = pathSegments.get(index);
|
||||||
|
|
|
@ -10,17 +10,17 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
class PathDecoderTest {
|
class PathDecoderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPlusSign() {
|
void testPlusSign() throws Exception {
|
||||||
PathDecoder decoder = new PathDecoder("/path?a=b+c", "d=e+f");
|
PathDecoder decoder = new PathDecoder("/path?a=b+c", "d=e+f");
|
||||||
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString());
|
||||||
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSlash() {
|
void testSlash() throws Exception {
|
||||||
PathDecoder decoder = new PathDecoder("path/foo/bar/?a=b+c", "d=e+f");
|
PathDecoder decoder = new PathDecoder("path/foo/bar/?a=b+c", "d=e+f");
|
||||||
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString());
|
||||||
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -30,23 +30,23 @@ class PathDecoderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSlashes() {
|
void testSlashes() throws Exception {
|
||||||
PathDecoder decoder = new PathDecoder("//path?a=b+c", "d=e+f");
|
PathDecoder decoder = new PathDecoder("//path?a=b+c", "d=e+f");
|
||||||
assertEquals("/path", decoder.path());
|
assertEquals("/path", decoder.path());
|
||||||
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString());
|
||||||
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPlusPercent() {
|
void testPlusPercent() throws Exception {
|
||||||
PathDecoder decoder = new PathDecoder("//path?a=b%2Bc", "d=e%2Bf");
|
PathDecoder decoder = new PathDecoder("//path?a=b%2Bc", "d=e%2Bf");
|
||||||
assertEquals("/path", decoder.path());
|
assertEquals("/path", decoder.path());
|
||||||
assertEquals("[b+c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[b+c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString());
|
||||||
assertEquals("[e+f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[e+f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void decodeURL() {
|
void decodeURL() throws Exception {
|
||||||
String requestURI = "/pdfconverter/index.gtpl?x-fl-key=20190035592&x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf&x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://xbib.org/ack/&x-fl-pages=1-";
|
String requestURI = "/pdfconverter/index.gtpl?x-fl-key=20190035592&x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf&x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://xbib.org/ack/&x-fl-pages=1-";
|
||||||
URL url = URL.builder().path(requestURI).build();
|
URL url = URL.builder().path(requestURI).build();
|
||||||
assertNull(url.getHost());
|
assertNull(url.getHost());
|
||||||
|
@ -59,7 +59,7 @@ class PathDecoderTest {
|
||||||
}
|
}
|
||||||
assertEquals("x-fl-key=20190035592&x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf&x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://xbib.org/ack/&x-fl-pages=1-", url.getDecodedQuery());
|
assertEquals("x-fl-key=20190035592&x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf&x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://xbib.org/ack/&x-fl-pages=1-", url.getDecodedQuery());
|
||||||
assertEquals("[x-fl-key=20190035592, x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf, x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf, x-fl-copy=, x-fl-ack=https://xbib.org/ack/, x-fl-pages=1-]", decoder.getParameter().toString());
|
assertEquals("[x-fl-key=20190035592, x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf, x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf, x-fl-copy=, x-fl-ack=https://xbib.org/ack/, x-fl-pages=1-]", decoder.getParameter().toString());
|
||||||
url = URL.from(decoder.getParameter().getAll("x-fl-target", Parameter.Domain.DEFAULT).get(0).toString());
|
url = URL.from(decoder.getParameter().getAll("x-fl-target", Parameter.Domain.PATH).get(0).toString());
|
||||||
assertEquals("ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf", url.toString());
|
assertEquals("ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf", url.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,38 +311,38 @@ class PathMatcherTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void extractUriTemplateVariablesRegex() {
|
void extractUriTemplateVariablesRegex() throws Exception {
|
||||||
Parameter result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar",
|
Parameter result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar",
|
||||||
"com.example-1.0.0.jar");
|
"com.example-1.0.0.jar");
|
||||||
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
|
||||||
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.PATH).get(0));
|
||||||
|
|
||||||
result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-sources-{version:[\\w\\.]+}.jar",
|
result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-sources-{version:[\\w\\.]+}.jar",
|
||||||
"com.example-sources-1.0.0.jar");
|
"com.example-sources-1.0.0.jar");
|
||||||
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
|
||||||
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.PATH).get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void extractUriTemplateVarsRegexQualifiers() {
|
void extractUriTemplateVarsRegexQualifiers() throws Exception {
|
||||||
Parameter result = pathMatcher.extractUriTemplateVariables(
|
Parameter result = pathMatcher.extractUriTemplateVariables(
|
||||||
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar",
|
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar",
|
||||||
"com.example-sources-1.0.0.jar");
|
"com.example-sources-1.0.0.jar");
|
||||||
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
|
||||||
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.PATH).get(0));
|
||||||
result = pathMatcher.extractUriTemplateVariables(
|
result = pathMatcher.extractUriTemplateVariables(
|
||||||
"{symbolicName:[\\w\\.]+}-sources-{version:[\\d\\.]+}-{year:\\d{4}}{month:\\d{2}}{day:\\d{2}}.jar",
|
"{symbolicName:[\\w\\.]+}-sources-{version:[\\d\\.]+}-{year:\\d{4}}{month:\\d{2}}{day:\\d{2}}.jar",
|
||||||
"com.example-sources-1.0.0-20100220.jar");
|
"com.example-sources-1.0.0-20100220.jar");
|
||||||
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
|
||||||
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.PATH).get(0));
|
||||||
assertEquals("2010", result.getAll("year", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("2010", result.getAll("year", Parameter.Domain.PATH).get(0));
|
||||||
assertEquals("02", result.getAll("month", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("02", result.getAll("month", Parameter.Domain.PATH).get(0));
|
||||||
assertEquals("20", result.getAll("day", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("20", result.getAll("day", Parameter.Domain.PATH).get(0));
|
||||||
result = pathMatcher.extractUriTemplateVariables(
|
result = pathMatcher.extractUriTemplateVariables(
|
||||||
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.\\{\\}]+}.jar",
|
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.\\{\\}]+}.jar",
|
||||||
"com.example-sources-1.0.0.{12}.jar");
|
"com.example-sources-1.0.0.{12}.jar");
|
||||||
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
|
||||||
assertEquals("1.0.0.{12}", result.getAll("version", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("1.0.0.{12}", result.getAll("version", Parameter.Domain.PATH).get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.xbib.net.path.simple;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
|
import org.xbib.net.ParameterException;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -18,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||||
class PathResolverTest {
|
class PathResolverTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void simple() {
|
void simple() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "explorer", 1234)
|
.add("GET", "explorer", 1234)
|
||||||
.build();
|
.build();
|
||||||
|
@ -29,7 +30,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void name() {
|
void name() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "/static/{file}", 1234)
|
.add("GET", "/static/{file}", 1234)
|
||||||
.add("HEAD", "/static/{file}", 1234)
|
.add("HEAD", "/static/{file}", 1234)
|
||||||
|
@ -39,7 +40,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void glob() {
|
void glob() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "/static/**", 1234)
|
.add("GET", "/static/**", 1234)
|
||||||
.build();
|
.build();
|
||||||
|
@ -48,7 +49,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void sharedPrefix() {
|
void sharedPrefix() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery/v1/rest", 1234)
|
.add("GET", "discovery/v1/rest", 1234)
|
||||||
.add("GET", "discovery/v2/rest", 4321)
|
.add("GET", "discovery/v2/rest", 4321)
|
||||||
|
@ -61,7 +62,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void prefix() {
|
void prefix() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery", 1234)
|
.add("GET", "discovery", 1234)
|
||||||
.add("GET", "discovery/v1", 4321)
|
.add("GET", "discovery/v1", 4321)
|
||||||
|
@ -72,7 +73,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void parameter() {
|
void parameter() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery/{version}/rest", 1234)
|
.add("GET", "discovery/{version}/rest", 1234)
|
||||||
.build();
|
.build();
|
||||||
|
@ -81,7 +82,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void multipleParameters() {
|
void multipleParameters() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234)
|
.add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234)
|
||||||
.build();
|
.build();
|
||||||
|
@ -90,7 +91,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void sharedParameterPrefix() {
|
void sharedParameterPrefix() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery/{version}/rest", 1234)
|
.add("GET", "discovery/{version}/rest", 1234)
|
||||||
.add("GET", "discovery/{version}/rpc", 4321)
|
.add("GET", "discovery/{version}/rpc", 4321)
|
||||||
|
@ -102,7 +103,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testResolveParameterAfterLiteral() {
|
void testResolveParameterAfterLiteral() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "{one}/three", 1234)
|
.add("GET", "{one}/three", 1234)
|
||||||
.add("GET", "one/two", 4321)
|
.add("GET", "one/two", 4321)
|
||||||
|
@ -112,7 +113,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testResolveBacktrack() {
|
void testResolveBacktrack() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "{one}/{two}/three/{four}", 1234)
|
.add("GET", "{one}/{two}/three/{four}", 1234)
|
||||||
.add("GET", "one/two/{three}/four", 4321)
|
.add("GET", "one/two/{three}/four", 4321)
|
||||||
|
@ -122,7 +123,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void pathMethodsWithDifferentParameterNames() {
|
void pathMethodsWithDifferentParameterNames() throws ParameterException {
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "test/{one}", 1234)
|
.add("GET", "test/{one}", 1234)
|
||||||
.add("PUT", "test/{two}", 4321)
|
.add("PUT", "test/{two}", 4321)
|
||||||
|
@ -142,7 +143,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void laxDuplicatePath() {
|
void laxDuplicatePath() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder(false)
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder(false)
|
||||||
.add("GET", "test/{one}", 1234)
|
.add("GET", "test/{one}", 1234)
|
||||||
.add("GET", "test/{two}", 4321)
|
.add("GET", "test/{two}", 4321)
|
||||||
|
@ -186,6 +187,8 @@ class PathResolverTest {
|
||||||
fail("expected NullPointerException");
|
fail("expected NullPointerException");
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// expected
|
// expected
|
||||||
|
} catch (ParameterException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +226,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFallback() {
|
void testFallback() throws ParameterException {
|
||||||
AtomicInteger counter = new AtomicInteger(0);
|
AtomicInteger counter = new AtomicInteger(0);
|
||||||
org.xbib.net.path.PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
org.xbib.net.path.PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add("GET", "/test/{one}", 1)
|
.add("GET", "/test/{one}", 1)
|
||||||
|
@ -247,16 +250,16 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSuccessfulGetResolution(PathResolver<Integer> trie, String path, Integer value) {
|
private void assertSuccessfulGetResolution(PathResolver<Integer> trie, String path, Integer value) throws ParameterException {
|
||||||
assertSuccessfulResolution(trie, "GET", path, value);
|
assertSuccessfulResolution(trie, "GET", path, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSuccessfulResolution(PathResolver<Integer> trie, String method, String path, Integer value) {
|
private void assertSuccessfulResolution(PathResolver<Integer> trie, String method, String path, Integer value) throws ParameterException {
|
||||||
assertSuccessfulResolution(trie, method, path, Set.of(value), Collections.emptyMap());
|
assertSuccessfulResolution(trie, method, path, Set.of(value), Collections.emptyMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSuccessfulGetResolution(PathResolver<Integer> trie, String path, Integer value,
|
private void assertSuccessfulGetResolution(PathResolver<Integer> trie, String path, Integer value,
|
||||||
Map<String, String> rawParameters) {
|
Map<String, String> rawParameters) throws ParameterException {
|
||||||
assertSuccessfulResolution(trie, "GET", path, Set.of(value), rawParameters);
|
assertSuccessfulResolution(trie, "GET", path, Set.of(value), rawParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,18 +267,18 @@ class PathResolverTest {
|
||||||
String method,
|
String method,
|
||||||
String path,
|
String path,
|
||||||
Set<Integer> values,
|
Set<Integer> values,
|
||||||
Map<String, String> rawParameters) {
|
Map<String, String> rawParameters) throws ParameterException {
|
||||||
trie.resolve(method, path, result -> {
|
trie.resolve(method, path, result -> {
|
||||||
assertTrue(values.contains(result.getValue()));
|
assertTrue(values.contains(result.getValue()));
|
||||||
//assertThat(result.getRawParameters(), is(rawParameters));
|
//assertThat(result.getRawParameters(), is(rawParameters));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertFailedGetResolution(PathResolver<Integer> trie, String path) {
|
private void assertFailedGetResolution(PathResolver<Integer> trie, String path) throws ParameterException {
|
||||||
assertFailedGetResolution(trie, "GET", path);
|
assertFailedGetResolution(trie, "GET", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertFailedGetResolution(PathResolver<Integer> trie, String method, String path) {
|
private void assertFailedGetResolution(PathResolver<Integer> trie, String method, String path) throws ParameterException {
|
||||||
trie.resolve(method, path, r-> { fail(); });
|
trie.resolve(method, path, r-> { fail(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.xbib.net.path.structure;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.xbib.net.Parameter;
|
import org.xbib.net.Parameter;
|
||||||
|
import org.xbib.net.ParameterException;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
@ -20,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||||
class PathResolverTest {
|
class PathResolverTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void example() {
|
void example() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add( "GET", "/static/{file}", 1234)
|
.add( "GET", "/static/{file}", 1234)
|
||||||
.build();
|
.build();
|
||||||
|
@ -29,7 +30,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void simple() {
|
void simple() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "explorer", 1234)
|
.add("GET", "explorer", 1234)
|
||||||
.build();
|
.build();
|
||||||
|
@ -39,7 +40,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void sharedPrefix() {
|
void sharedPrefix() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery/v1/rest", 1234)
|
.add("GET", "discovery/v1/rest", 1234)
|
||||||
.add("GET", "discovery/v2/rest", 4321)
|
.add("GET", "discovery/v2/rest", 4321)
|
||||||
|
@ -52,7 +53,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void prefix() {
|
void prefix() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery", 1234)
|
.add("GET", "discovery", 1234)
|
||||||
.add("GET", "discovery/v1", 4321)
|
.add("GET", "discovery/v1", 4321)
|
||||||
|
@ -63,7 +64,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void parameter() {
|
void parameter() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery/{version}/rest", 1234)
|
.add("GET", "discovery/{version}/rest", 1234)
|
||||||
.build();
|
.build();
|
||||||
|
@ -72,7 +73,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void multipleParameters() {
|
void multipleParameters() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234)
|
.add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234)
|
||||||
.build();
|
.build();
|
||||||
|
@ -81,7 +82,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void sharedParameterPrefix() {
|
void sharedParameterPrefix() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "discovery/{version}/rest", 1234)
|
.add("GET", "discovery/{version}/rest", 1234)
|
||||||
.add("GET", "discovery/{version}/rpc", 4321)
|
.add("GET", "discovery/{version}/rpc", 4321)
|
||||||
|
@ -97,7 +98,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testResolveParameterAfterLiteral() {
|
void testResolveParameterAfterLiteral() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "{one}/three", 1234)
|
.add("GET", "{one}/three", 1234)
|
||||||
.add("GET", "one/two", 4321)
|
.add("GET", "one/two", 4321)
|
||||||
|
@ -108,7 +109,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testResolveBacktrack() {
|
void testResolveBacktrack() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "{one}/{two}/three/{four}", 1234)
|
.add("GET", "{one}/{two}/three/{four}", 1234)
|
||||||
.add("GET", "one/two/{three}/four", 4321)
|
.add("GET", "one/two/{three}/four", 4321)
|
||||||
|
@ -128,7 +129,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void pathMethodsWithDifferentParameterNames() {
|
void pathMethodsWithDifferentParameterNames() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "test/{one}", 1234)
|
.add("GET", "test/{one}", 1234)
|
||||||
.add("GET", "test/{two}", 4321)
|
.add("GET", "test/{two}", 4321)
|
||||||
|
@ -148,7 +149,7 @@ class PathResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void duplicatePathParams() {
|
void duplicatePathParams() throws ParameterException {
|
||||||
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
|
||||||
.add("GET", "test/{one}", 1234)
|
.add("GET", "test/{one}", 1234)
|
||||||
.add("GET", "test/{two}", 4321)
|
.add("GET", "test/{two}", 4321)
|
||||||
|
@ -197,11 +198,13 @@ class PathResolverTest {
|
||||||
fail("expected NullPointerException");
|
fail("expected NullPointerException");
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// expected
|
// expected
|
||||||
|
} catch (ParameterException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFallback() {
|
void testFallback() throws ParameterException {
|
||||||
AtomicInteger counter = new AtomicInteger(0);
|
AtomicInteger counter = new AtomicInteger(0);
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add( "GET", "/test/{one}", 1)
|
.add( "GET", "/test/{one}", 1)
|
||||||
|
@ -216,7 +219,7 @@ class PathResolverTest {
|
||||||
|
|
||||||
@Disabled
|
@Disabled
|
||||||
@Test
|
@Test
|
||||||
void testSuffixCatchAll() {
|
void testSuffixCatchAll() throws ParameterException {
|
||||||
AtomicInteger counter = new AtomicInteger(0);
|
AtomicInteger counter = new AtomicInteger(0);
|
||||||
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
PathResolver<Integer> trie = PathResolver.<Integer>builder()
|
||||||
.add( "GET", "/**/*.test", 1)
|
.add( "GET", "/**/*.test", 1)
|
||||||
|
@ -229,12 +232,12 @@ class PathResolverTest {
|
||||||
assertThat(counter.get(), equalTo(2));
|
assertThat(counter.get(), equalTo(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSuccessfulResolution(PathResolver<Integer> pathResolver, String path, Integer value) {
|
private void assertSuccessfulResolution(PathResolver<Integer> pathResolver, String path, Integer value) throws ParameterException {
|
||||||
assertSuccessfulResolution(pathResolver, "GET", path, value, Parameter.builder().domain(Parameter.Domain.PATH).build());
|
assertSuccessfulResolution(pathResolver, "GET", path, value, Parameter.builder().domain(Parameter.Domain.PATH).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSuccessfulResolution(PathResolver<Integer> pathResolver, String method, String path, Integer value,
|
private void assertSuccessfulResolution(PathResolver<Integer> pathResolver, String method, String path, Integer value,
|
||||||
Parameter parameter) {
|
Parameter parameter) throws ParameterException {
|
||||||
AtomicBoolean found = new AtomicBoolean(false);
|
AtomicBoolean found = new AtomicBoolean(false);
|
||||||
pathResolver.resolve(method, path, result -> {
|
pathResolver.resolve(method, path, result -> {
|
||||||
assertThat(result, notNullValue());
|
assertThat(result, notNullValue());
|
||||||
|
@ -246,7 +249,7 @@ class PathResolverTest {
|
||||||
assertTrue(found.get());
|
assertTrue(found.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertFailedGetResolution(PathResolver<Integer> pathResolver, String path) {
|
private void assertFailedGetResolution(PathResolver<Integer> pathResolver, String path) throws ParameterException {
|
||||||
pathResolver.resolve("GET", path, r -> assertThat(r, nullValue()));
|
pathResolver.resolve("GET", path, r -> assertThat(r, nullValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import org.xbib.datastructures.common.Pair;
|
||||||
public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Parameter> {
|
public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Parameter> {
|
||||||
|
|
||||||
public enum Domain {
|
public enum Domain {
|
||||||
DEFAULT,
|
UNDEFINED,
|
||||||
QUERY,
|
QUERY,
|
||||||
FORM,
|
FORM,
|
||||||
PATH,
|
PATH,
|
||||||
|
@ -92,7 +92,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public String getAsString(String key, Domain domain) {
|
public String getAsString(String key, Domain domain) throws ParameterException {
|
||||||
Object object = get(key, domain);
|
Object object = get(key, domain);
|
||||||
if (object instanceof Collection) {
|
if (object instanceof Collection) {
|
||||||
Collection<Object> collection = (Collection<Object>) object;
|
Collection<Object> collection = (Collection<Object>) object;
|
||||||
|
@ -108,7 +108,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Integer getAsInteger(String key, Domain domain) {
|
public Integer getAsInteger(String key, Domain domain) throws ParameterException {
|
||||||
Object object = get(key, domain);
|
Object object = get(key, domain);
|
||||||
if (object instanceof Collection) {
|
if (object instanceof Collection) {
|
||||||
Collection<Object> collection = (Collection<Object>) object;
|
Collection<Object> collection = (Collection<Object>) object;
|
||||||
|
@ -128,7 +128,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Boolean getAsBoolean(String key, Domain domain) {
|
public Boolean getAsBoolean(String key, Domain domain) throws ParameterException {
|
||||||
Object object = get(key, domain);
|
Object object = get(key, domain);
|
||||||
if (object instanceof Collection) {
|
if (object instanceof Collection) {
|
||||||
Collection<Object> collection = (Collection<Object>) object;
|
Collection<Object> collection = (Collection<Object>) object;
|
||||||
|
@ -147,49 +147,35 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String allToString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(list.toString());
|
|
||||||
builder.parameterMap.forEach((key, value) -> sb.append(" ").append(key).append(" -> ").append(value));
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasElements() {
|
public boolean hasElements() {
|
||||||
return !list.isEmpty();
|
return !list.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiMap<String, Object> asMultiMap() {
|
public MultiMap<String, Object> asMultiMap() throws ParameterException{
|
||||||
|
if (getDomain() == Domain.UNDEFINED) {
|
||||||
|
throw new ParameterException("undefined domain");
|
||||||
|
}
|
||||||
MultiMap<String, Object> multiMap = new LinkedHashSetMultiMap<>();
|
MultiMap<String, Object> multiMap = new LinkedHashSetMultiMap<>();
|
||||||
this.forEach(p -> multiMap.put(p.getKey(), p.getValue()));
|
this.forEach(p -> multiMap.put(p.getKey(), p.getValue()));
|
||||||
return multiMap;
|
return multiMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> asSingleValuedMap() {
|
public Map<String, Object> asSingleValuedMap() throws ParameterException {
|
||||||
|
if (getDomain() == Domain.UNDEFINED) {
|
||||||
|
throw new ParameterException("undefined domain");
|
||||||
|
}
|
||||||
Map<String, Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
this.forEach(p -> map.put(p.getKey(), createValue(p.getValue())));
|
this.forEach(p -> map.put(p.getKey(), createValue(p.getValue())));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public List<Object> getAllInDomain(Domain domain) {
|
||||||
private static Object createValue(Object object) {
|
|
||||||
if (object instanceof Collection) {
|
|
||||||
Collection<Object> collection = (Collection<Object>) object;
|
|
||||||
if (collection.size() == 1) {
|
|
||||||
return collection.iterator().next();
|
|
||||||
} else {
|
|
||||||
return collection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Object> getAllDomain(Domain domain) {
|
|
||||||
Parameter parameter = null;
|
Parameter parameter = null;
|
||||||
if (builder.parameterMap.containsKey(domain)) {
|
if (builder.parameterMap.containsKey(domain)) {
|
||||||
parameter = builder.parameterMap.get(domain);
|
parameter = builder.parameterMap.get(domain);
|
||||||
}
|
}
|
||||||
if (parameter != null) {
|
if (parameter != null) {
|
||||||
return parameter.getAllDomain(domain);
|
return parameter.getAllInDomain(domain);
|
||||||
}
|
}
|
||||||
if (getDomain().equals(domain)) {
|
if (getDomain().equals(domain)) {
|
||||||
return list.stream()
|
return list.stream()
|
||||||
|
@ -213,7 +199,10 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Parameter getDomain(Domain domain) {
|
public Parameter get(Domain domain) throws ParameterException {
|
||||||
|
if (getDomain() == Domain.UNDEFINED) {
|
||||||
|
throw new ParameterException("undefined domain");
|
||||||
|
}
|
||||||
if (builder.parameterMap.containsKey(domain)) {
|
if (builder.parameterMap.containsKey(domain)) {
|
||||||
return builder.parameterMap.get(domain);
|
return builder.parameterMap.get(domain);
|
||||||
}
|
}
|
||||||
|
@ -223,7 +212,10 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Object> getAll(String key, Domain domain) {
|
public List<Object> getAll(String key, Domain domain) throws Exception {
|
||||||
|
if (getDomain() == Domain.UNDEFINED) {
|
||||||
|
throw new ParameterException("undefined domain");
|
||||||
|
}
|
||||||
Parameter parameter = null;
|
Parameter parameter = null;
|
||||||
if (builder.parameterMap.containsKey(domain)) {
|
if (builder.parameterMap.containsKey(domain)) {
|
||||||
parameter = builder.parameterMap.get(domain);
|
parameter = builder.parameterMap.get(domain);
|
||||||
|
@ -255,7 +247,10 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(String key, Domain domain) {
|
public Object get(String key, Domain domain) throws ParameterException {
|
||||||
|
if (getDomain() == Domain.UNDEFINED) {
|
||||||
|
throw new ParameterException("undefined domain");
|
||||||
|
}
|
||||||
Parameter parameter = null;
|
Parameter parameter = null;
|
||||||
if (builder.parameterMap.containsKey(domain)) {
|
if (builder.parameterMap.containsKey(domain)) {
|
||||||
parameter = builder.parameterMap.get(domain);
|
parameter = builder.parameterMap.get(domain);
|
||||||
|
@ -278,4 +273,24 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
|
||||||
public String getAsQueryString() {
|
public String getAsQueryString() {
|
||||||
return queryString;
|
return queryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String allToString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(list.toString());
|
||||||
|
builder.parameterMap.forEach((key, value) -> sb.append(" ").append(key).append(" -> ").append(value));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static Object createValue(Object object) {
|
||||||
|
if (object instanceof Collection) {
|
||||||
|
Collection<Object> collection = (Collection<Object>) object;
|
||||||
|
if (collection.size() == 1) {
|
||||||
|
return collection.iterator().next();
|
||||||
|
} else {
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class ParameterBuilder implements PairValidator {
|
||||||
ParameterBuilder() {
|
ParameterBuilder() {
|
||||||
this.list = new ArrayList<>();
|
this.list = new ArrayList<>();
|
||||||
this.parameterMap = new HashMap<>();
|
this.parameterMap = new HashMap<>();
|
||||||
this.domain = Parameter.Domain.DEFAULT;
|
this.domain = Parameter.Domain.UNDEFINED;
|
||||||
this.limit = 0;
|
this.limit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
9
net/src/main/java/org/xbib/net/ParameterException.java
Normal file
9
net/src/main/java/org/xbib/net/ParameterException.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package org.xbib.net;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ParameterException extends Exception {
|
||||||
|
|
||||||
|
public ParameterException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -82,7 +82,7 @@ public class URLBuilder {
|
||||||
.onMalformedInput(codingErrorAction)
|
.onMalformedInput(codingErrorAction)
|
||||||
.onUnmappableCharacter(codingErrorAction);
|
.onUnmappableCharacter(codingErrorAction);
|
||||||
this.percentDecoder = new PercentDecoder(charsetDecoder);
|
this.percentDecoder = new PercentDecoder(charsetDecoder);
|
||||||
this.queryParams = Parameter.builder();
|
this.queryParams = Parameter.builder().domain(Parameter.Domain.QUERY);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +301,6 @@ public class URLBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A path segment with associated matrix params, if any.
|
* A path segment with associated matrix params, if any.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,33 +17,35 @@ public class ParameterTest {
|
||||||
public void testEmptyBuilder() {
|
public void testEmptyBuilder() {
|
||||||
Parameter parameter = Parameter.builder().build();
|
Parameter parameter = Parameter.builder().build();
|
||||||
assertNotNull(parameter);
|
assertNotNull(parameter);
|
||||||
assertFalse(parameter.containsKey("param1", Parameter.Domain.DEFAULT));
|
assertFalse(parameter.containsKey("param1", Parameter.Domain.UNDEFINED));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSingleParameter() {
|
public void testSingleParameter() {
|
||||||
Parameter parameter = Parameter.builder()
|
Parameter parameter = Parameter.builder()
|
||||||
|
.domain(Parameter.Domain.QUERY)
|
||||||
.add("Hello", "World")
|
.add("Hello", "World")
|
||||||
.build();
|
.build();
|
||||||
assertNotNull(parameter);
|
assertNotNull(parameter);
|
||||||
assertTrue(parameter.containsKey("Hello", Parameter.Domain.DEFAULT));
|
assertTrue(parameter.containsKey("Hello", Parameter.Domain.QUERY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateParameter() {
|
public void testDuplicateParameter() throws Exception {
|
||||||
Parameter parameter = Parameter.builder()
|
Parameter parameter = Parameter.builder()
|
||||||
|
.domain(Parameter.Domain.QUERY)
|
||||||
.enableDuplicates()
|
.enableDuplicates()
|
||||||
.add("Hello", "World")
|
.add("Hello", "World")
|
||||||
.add("Hello", "World")
|
.add("Hello", "World")
|
||||||
.add("Hello", "World")
|
.add("Hello", "World")
|
||||||
.build();
|
.build();
|
||||||
assertNotNull(parameter);
|
assertNotNull(parameter);
|
||||||
assertTrue(parameter.containsKey("Hello", Parameter.Domain.DEFAULT));
|
assertTrue(parameter.containsKey("Hello", Parameter.Domain.QUERY));
|
||||||
assertEquals(List.of("World", "World", "World"), parameter.getAll("Hello", Parameter.Domain.DEFAULT));
|
assertEquals(List.of("World", "World", "World"), parameter.getAll("Hello", Parameter.Domain.QUERY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHttpHeaderParameter() {
|
public void testHttpHeaderParameter() throws Exception {
|
||||||
Parameter parameter = Parameter.builder()
|
Parameter parameter = Parameter.builder()
|
||||||
.charset(StandardCharsets.US_ASCII)
|
.charset(StandardCharsets.US_ASCII)
|
||||||
.lowercase()
|
.lowercase()
|
||||||
|
@ -116,20 +118,20 @@ public class ParameterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSimpleParse() {
|
void testSimpleParse() throws Exception {
|
||||||
ParameterBuilder queryParameters = Parameter.builder();
|
ParameterBuilder queryParameters = Parameter.builder().domain(Parameter.Domain.QUERY);
|
||||||
String body = "a=b&c=d&e=f";
|
String body = "a=b&c=d&e=f";
|
||||||
queryParameters.addPercentEncodedBody(body);
|
queryParameters.addPercentEncodedBody(body);
|
||||||
Parameter parameter = queryParameters.build();
|
Parameter parameter = queryParameters.build();
|
||||||
assertEquals("b", parameter.getAll("a", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("b", parameter.getAll("a", Parameter.Domain.QUERY).get(0));
|
||||||
assertEquals("d", parameter.getAll("c", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("d", parameter.getAll("c", Parameter.Domain.QUERY).get(0));
|
||||||
assertEquals("f", parameter.getAll("e", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("f", parameter.getAll("e", Parameter.Domain.QUERY).get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParseExceedingParamLimit() {
|
void testParseExceedingParamLimit() {
|
||||||
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
||||||
ParameterBuilder queryParameters = Parameter.builder().limit(100);
|
ParameterBuilder queryParameters = Parameter.builder().domain(Parameter.Domain.QUERY).limit(100);
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
for (int i = 0; i < 200; i++) {
|
for (int i = 0; i < 200; i++) {
|
||||||
list.add("a" + i + "=b" + i);
|
list.add("a" + i + "=b" + i);
|
||||||
|
@ -137,18 +139,19 @@ public class ParameterTest {
|
||||||
String body = String.join("&", list);
|
String body = String.join("&", list);
|
||||||
queryParameters.addPercentEncodedBody(body);
|
queryParameters.addPercentEncodedBody(body);
|
||||||
Parameter parameter = queryParameters.build();
|
Parameter parameter = queryParameters.build();
|
||||||
assertEquals("b0", parameter.getAll("a0", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("b0", parameter.getAll("a0", Parameter.Domain.QUERY).get(0));
|
||||||
assertEquals("b99", parameter.getAll("a99", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("b99", parameter.getAll("a99", Parameter.Domain.QUERY).get(0));
|
||||||
assertEquals("[]", parameter.getAll("a100", Parameter.Domain.DEFAULT).toString());
|
assertEquals("[]", parameter.getAll("a100", Parameter.Domain.QUERY).toString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDomains() {
|
void testDomains() throws ParameterException {
|
||||||
Parameter p1 = Parameter.builder().domain(Parameter.Domain.QUERY).add("a", "a").build();
|
Parameter p1 = Parameter.builder().domain(Parameter.Domain.QUERY).add("a", "a").build();
|
||||||
Parameter p2 = Parameter.builder().domain(Parameter.Domain.FORM).add("b", "b").build();
|
Parameter p2 = Parameter.builder().domain(Parameter.Domain.FORM).add("b", "b").build();
|
||||||
Parameter p3 = Parameter.builder().domain(Parameter.Domain.HEADER).add("c", "c").build();
|
Parameter p3 = Parameter.builder().domain(Parameter.Domain.HEADER).add("c", "c").build();
|
||||||
Parameter p = Parameter.builder()
|
Parameter p = Parameter.builder()
|
||||||
|
.domain(Parameter.Domain.QUERY)
|
||||||
.add(p1)
|
.add(p1)
|
||||||
.add(p2)
|
.add(p2)
|
||||||
.add(p3)
|
.add(p3)
|
||||||
|
@ -162,6 +165,5 @@ public class ParameterTest {
|
||||||
assertTrue(p.isPresent(Parameter.Domain.QUERY));
|
assertTrue(p.isPresent(Parameter.Domain.QUERY));
|
||||||
assertTrue(p.isPresent(Parameter.Domain.FORM));
|
assertTrue(p.isPresent(Parameter.Domain.FORM));
|
||||||
assertTrue(p.isPresent(Parameter.Domain.HEADER));
|
assertTrue(p.isPresent(Parameter.Domain.HEADER));
|
||||||
assertFalse(p.isPresent(Parameter.Domain.DEFAULT));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ class URLParserTest {
|
||||||
assertEquals("path", pathSegment.getSegment());
|
assertEquals("path", pathSegment.getSegment());
|
||||||
assertEquals("p2", pathSegment.getMatrixParams().get(0).getKey());
|
assertEquals("p2", pathSegment.getMatrixParams().get(0).getKey());
|
||||||
assertEquals("v2", pathSegment.getMatrixParams().get(0).getValue());
|
assertEquals("v2", pathSegment.getMatrixParams().get(0).getValue());
|
||||||
assertEquals("v3", url.getQueryParams().getAll("q1", Parameter.Domain.DEFAULT).get(0));
|
assertEquals("v3", url.getQueryParams().getAll("q1", Parameter.Domain.QUERY).get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in a new issue