|
|
@@ -8,33 +8,28 @@ package net.ranides.assira.io.uri;
|
|
|
|
|
|
import java.net.URI;
|
|
|
import java.net.URISyntaxException;
|
|
|
-import java.util.AbstractMap;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.Collection;
|
|
|
-import java.util.Iterator;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
import java.util.Map.Entry;
|
|
|
-import java.util.Optional;
|
|
|
-import java.util.Set;
|
|
|
-import java.util.function.Function;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
import java.util.stream.Collectors;
|
|
|
import net.ranides.assira.collection.maps.AMap;
|
|
|
import net.ranides.assira.collection.maps.MapBuilder;
|
|
|
import net.ranides.assira.collection.maps.MultiMap;
|
|
|
import net.ranides.assira.generic.CompareUtils;
|
|
|
-import net.ranides.assira.text.ResolveFormatUtils;
|
|
|
-import net.ranides.assira.text.StrBuilder;
|
|
|
-import net.ranides.assira.text.StringTraits;
|
|
|
-import net.ranides.assira.text.StringUtils;
|
|
|
+import net.ranides.assira.reflection.util.ResolveUtils;
|
|
|
+import net.ranides.assira.text.*;
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
* @author Ranides Atterwim <ranides@gmail.com>
|
|
|
*/
|
|
|
public class URIBuilder {
|
|
|
-
|
|
|
+
|
|
|
+ // scheme login password host port path params fragment
|
|
|
+ // 1 2 3 4 5 6 7 8
|
|
|
+ private static final Pattern RE_URL = Pattern.compile("([^:]+)://(?:([^:@]+)(?::([^@]+))?@)?([^/:?#]+)?(?::([^/?#]+))?(/[^?#]+)?(?:\\?([^?#]*))?(?:#(.+))?");
|
|
|
+
|
|
|
private String scheme;
|
|
|
private String host;
|
|
|
private String port;
|
|
|
@@ -51,7 +46,18 @@ public class URIBuilder {
|
|
|
}
|
|
|
|
|
|
public URIBuilder(String uri) {
|
|
|
- this(parse(uri));
|
|
|
+ Matcher matcher = RE_URL.matcher(uri);
|
|
|
+ if(!matcher.matches()) {
|
|
|
+ throw new IllegalArgumentException("Invalid URI: " + uri);
|
|
|
+ }
|
|
|
+ this.scheme = matcher.group(1);
|
|
|
+ this.login = matcher.group(2);
|
|
|
+ this.password = matcher.group(3);
|
|
|
+ this.host = matcher.group(4);
|
|
|
+ this.port = matcher.group(5);
|
|
|
+ this.path = matcher.group(6);
|
|
|
+ this.params = new ParamMap(matcher.group(7));
|
|
|
+ this.fragment = matcher.group(8);
|
|
|
}
|
|
|
|
|
|
public URIBuilder(URI uri) {
|
|
|
@@ -85,8 +91,8 @@ public class URIBuilder {
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- public String host() {
|
|
|
- return host;
|
|
|
+ public Optional<String> host() {
|
|
|
+ return Optional.ofNullable(host);
|
|
|
}
|
|
|
|
|
|
public URIBuilder host(String value) {
|
|
|
@@ -174,17 +180,15 @@ public class URIBuilder {
|
|
|
}
|
|
|
|
|
|
public URIBuilder resolve(Object context) {
|
|
|
- Function<String,String> r = resolver(context);
|
|
|
-
|
|
|
URIBuilder out = new URIBuilder();
|
|
|
- out.scheme = r.apply(scheme);
|
|
|
- out.host = r.apply(host);
|
|
|
- out.port = r.apply(port);
|
|
|
- out.path = r.apply(path);
|
|
|
- out.fragment = r.apply(fragment);
|
|
|
- out.params = resolve(r, params);
|
|
|
- out.login = r.apply(login);
|
|
|
- out.password = r.apply(password);
|
|
|
+ out.scheme = resolveFormat(scheme, context);
|
|
|
+ out.host = resolveFormat(host, context);
|
|
|
+ out.port = resolveFormat(port, context);
|
|
|
+ out.path = resolveFormat(path, context);
|
|
|
+ out.fragment = resolveFormat(fragment, context);
|
|
|
+ out.params = resolveParams(params, context);
|
|
|
+ out.login = resolveFormat(login, context);
|
|
|
+ out.password = resolveFormat(password, context);
|
|
|
|
|
|
return out;
|
|
|
}
|
|
|
@@ -250,21 +254,50 @@ public class URIBuilder {
|
|
|
private static String paramValue(String[] array) {
|
|
|
return array.length > 1 ? array[1] : "";
|
|
|
}
|
|
|
-
|
|
|
- private static Function<String,String> resolver(Object context) {
|
|
|
- return value -> null == value ? null : ResolveFormatUtils.format(value, context);
|
|
|
+
|
|
|
+
|
|
|
+ private static String resolveFormat(String value, Object context) {
|
|
|
+ return null == value ? null : ResolveFormatUtils.format(value, context);
|
|
|
}
|
|
|
-
|
|
|
- private static ParamMap resolve(Function<String,String> resolver, ParamMap map) {
|
|
|
+
|
|
|
+ private static ParamMap resolveParams(ParamMap map, Object context) {
|
|
|
ParamMap out = new ParamMap();
|
|
|
for(Entry<String,String> entry : map.set) {
|
|
|
- out.set.add( newEntry(entry, resolver.apply(entry.getKey()), resolver.apply(entry.getValue())) );
|
|
|
+ String key = resolveFormat(entry.getKey(), context);
|
|
|
+ if(entry.getValue() == null) {
|
|
|
+ out.set.add( newEntry(entry, key, null) );
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ List<String> list = resolveList(entry.getValue(), context);
|
|
|
+ if(list != null) {
|
|
|
+ for(String item : list) {
|
|
|
+ out.set.add(new ParamEntry(key, item));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ out.set.add(newEntry(entry, entry.getKey(), ResolveFormatUtils.format(entry.getValue(), context)));
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
+ private static List<String> resolveList(String value, Object context) {
|
|
|
+ if(isExpression(value)) {
|
|
|
+ String expression = value.substring(2, value.length() - 2);
|
|
|
+ Object object = ResolveUtils.get(context, expression);
|
|
|
+ if(object instanceof List) {
|
|
|
+ return ((List<?>)object).stream().map(String::valueOf).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isExpression(String value) {
|
|
|
+ return value!=null && value.startsWith("{{") && value.endsWith("}}");
|
|
|
+ }
|
|
|
+
|
|
|
private static Entry<String, String> newEntry(Entry<String, String> e, String key, String value) {
|
|
|
- return value.equals(e.getValue()) && key.equals(e.getKey()) ? e :new ParamEntry(key, value);
|
|
|
+ return Objects.equals(value, e.getValue()) && Objects.equals(key, e.getKey()) ? e : new ParamEntry(key, value);
|
|
|
}
|
|
|
|
|
|
|