remove our immutable list from Parameter, add copy constructor to URLBuilder

This commit is contained in:
Jörg Prante 2024-01-03 13:30:57 +01:00
parent e656f2d2bd
commit c45bbfca53
7 changed files with 59 additions and 28 deletions

View file

@ -1,3 +1,3 @@
group = org.xbib group = org.xbib
name = net name = net
version = 4.0.3 version = 4.0.4

View file

@ -10,7 +10,6 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.xbib.datastructures.common.ImmutableList;
import org.xbib.datastructures.common.LinkedHashSetMultiMap; import org.xbib.datastructures.common.LinkedHashSetMultiMap;
import org.xbib.datastructures.common.MultiMap; import org.xbib.datastructures.common.MultiMap;
import org.xbib.datastructures.common.Pair; import org.xbib.datastructures.common.Pair;
@ -30,15 +29,11 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
private final ParameterBuilder builder; private final ParameterBuilder builder;
private final ImmutableList<Pair<String, Object>> list;
private final String queryString; private final String queryString;
Parameter(ParameterBuilder builder, Parameter(ParameterBuilder builder,
ImmutableList<Pair<String, Object>> list,
String queryString) { String queryString) {
this.builder = builder; this.builder = builder;
this.list = list;
this.queryString = queryString; this.queryString = queryString;
} }
@ -64,24 +59,24 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
@Override @Override
public Iterator<Pair<String, Object>> iterator() { public Iterator<Pair<String, Object>> iterator() {
return list.iterator(); return builder.list.iterator();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
return o instanceof Parameter && return o instanceof Parameter &&
builder.domain.equals(((Parameter) o).builder.domain) && builder.domain.equals(((Parameter) o).builder.domain) &&
list.equals(((Parameter) o).list); builder.list.equals(((Parameter) o).builder.list);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(builder.domain, list); return Objects.hash(builder.domain, builder.list);
} }
@Override @Override
public int compareTo(Parameter o) { public int compareTo(Parameter o) {
return list.toString().compareTo(o.list.toString()); return builder.list.toString().compareTo(o.builder.list.toString());
} }
@Override @Override
@ -158,7 +153,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
} }
public boolean hasElements() { public boolean hasElements() {
return !list.isEmpty(); return !builder.list.isEmpty();
} }
public MultiMap<String, Object> asMultiMap() throws ParameterException{ public MultiMap<String, Object> asMultiMap() throws ParameterException{
@ -188,7 +183,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
return parameter.getAllInDomain(domain); return parameter.getAllInDomain(domain);
} }
if (getDomain().equals(domain)) { if (getDomain().equals(domain)) {
return list.stream() return builder.list.stream()
.map(Pair::getValue) .map(Pair::getValue)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -204,7 +199,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
return parameter.isPresent(domain); return parameter.isPresent(domain);
} }
if (getDomain().equals(domain)) { if (getDomain().equals(domain)) {
return list.stream().findAny().isPresent(); return builder.list.stream().findAny().isPresent();
} }
return false; return false;
} }
@ -234,7 +229,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
throw new ParameterException("undefined domain"); throw new ParameterException("undefined domain");
} }
if (getDomain().equals(domain)) { if (getDomain().equals(domain)) {
return list.stream() return builder.list.stream()
.filter(p -> p.getKey().equals(key)) .filter(p -> p.getKey().equals(key))
.map(Pair::getValue) .map(Pair::getValue)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -251,7 +246,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
return parameter.containsKey(key, domain); return parameter.containsKey(key, domain);
} }
if (getDomain().equals(domain)) { if (getDomain().equals(domain)) {
return list.stream() return builder.list.stream()
.anyMatch(p -> key.equals(p.getKey())); .anyMatch(p -> key.equals(p.getKey()));
} }
return false; return false;
@ -269,7 +264,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
throw new ParameterException("undefined domain, please specify domain for parameter " + this); throw new ParameterException("undefined domain, please specify domain for parameter " + this);
} }
if (getDomain().equals(domain)) { if (getDomain().equals(domain)) {
Optional<Object> optional = list.stream() Optional<Object> optional = builder.list.stream()
.filter(p -> key.equals(p.getKey())) .filter(p -> key.equals(p.getKey()))
.map(Pair::getValue) .map(Pair::getValue)
.findFirst(); .findFirst();
@ -286,7 +281,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
private String allToString() { private String allToString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(list.toString()); sb.append(builder.list.toString());
builder.parameterMap.forEach((key, value) -> sb.append(" ").append(key).append(" -> ").append(value)); builder.parameterMap.forEach((key, value) -> sb.append(" ").append(key).append(" -> ").append(value));
return sb.toString(); return sb.toString();
} }

View file

@ -1,7 +1,6 @@
package org.xbib.net; package org.xbib.net;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;
import java.lang.reflect.Array;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.CodingErrorAction; import java.nio.charset.CodingErrorAction;
import java.nio.charset.MalformedInputException; import java.nio.charset.MalformedInputException;
@ -16,23 +15,19 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.xbib.datastructures.common.ImmutableList;
import org.xbib.datastructures.common.MultiMap; import org.xbib.datastructures.common.MultiMap;
import org.xbib.datastructures.common.Pair; import org.xbib.datastructures.common.Pair;
import org.xbib.datastructures.common.PairValidator; import org.xbib.datastructures.common.PairValidator;
public class ParameterBuilder implements PairValidator { public class ParameterBuilder implements PairValidator {
@SuppressWarnings("unchecked")
private static final Pair<String, Object>[] EMPTY_PAIR = (Pair<String, Object>[]) Array.newInstance(Pair.class, 0);
private static final char AMPERSAND_CHAR = '&'; private static final char AMPERSAND_CHAR = '&';
private static final char EQUAL_CHAR = '='; private static final char EQUAL_CHAR = '=';
private static final Integer MAX_PARAMS_IN_QUERY_STRING = 1024; private static final Integer MAX_PARAMS_IN_QUERY_STRING = 1024;
private final List<Pair<String, Object>> list; final List<Pair<String, Object>> list;
protected Parameter.Domain domain; protected Parameter.Domain domain;
@ -72,8 +67,8 @@ public class ParameterBuilder implements PairValidator {
} }
ParameterBuilder(ParameterBuilder builder) { ParameterBuilder(ParameterBuilder builder) {
this.list = builder.list; this.list = new ArrayList<>(builder.list);
this.parameterMap = builder.parameterMap; this.parameterMap = new HashMap<>(builder.parameterMap);
this.domain = builder.domain; this.domain = builder.domain;
this.limit = builder.limit; this.limit = builder.limit;
this.charset = builder.charset; this.charset = builder.charset;
@ -266,7 +261,7 @@ public class ParameterBuilder implements PairValidator {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
} }
} }
Parameter parameter = new Parameter(this, ImmutableList.of(list, EMPTY_PAIR), queryString); Parameter parameter = new Parameter(this, queryString);
if (parameterValidator != null) { if (parameterValidator != null) {
return parameterValidator.apply(parameter); return parameterValidator.apply(parameter);
} else { } else {

View file

@ -67,7 +67,7 @@ public class URL implements Comparable<URL> {
static final String DOUBLE_SLASH = "//"; static final String DOUBLE_SLASH = "//";
private final transient URLBuilder builder; final transient URLBuilder builder;
private final transient Scheme scheme; private final transient Scheme scheme;
@ -111,6 +111,10 @@ public class URL implements Comparable<URL> {
return new URLBuilder(); return new URLBuilder();
} }
public static URLBuilder builder(URL url) {
return new URLBuilder(url.builder);
}
public static URLBuilder http() { public static URLBuilder http() {
return new URLBuilder().scheme(Scheme.HTTP); return new URLBuilder().scheme(Scheme.HTTP);
} }
@ -144,6 +148,15 @@ public class URL implements Comparable<URL> {
return NULL_URL; return NULL_URL;
} }
/**
* Copy URL.
* @param url the url
* @return a new URL object
*/
public static URL from(URL url) {
return builder(url).build();
}
public static URL from(String input) { public static URL from(String input) {
return from(input, StandardCharsets.UTF_8, CodingErrorAction.REPORT, true, false); return from(input, StandardCharsets.UTF_8, CodingErrorAction.REPORT, true, false);
} }

View file

@ -66,6 +66,26 @@ public class URLBuilder {
charset(StandardCharsets.UTF_8, CodingErrorAction.REPLACE); charset(StandardCharsets.UTF_8, CodingErrorAction.REPLACE);
} }
URLBuilder(URLBuilder builder) {
regNameEncoder = builder.regNameEncoder;
percentEncoder = builder.percentEncoder;
percentDecoder = builder.percentDecoder;
queryParams = Parameter.builder(builder.queryParams);
pathSegments = builder.pathSegments;
charset = builder.charset;
codingErrorAction = builder.codingErrorAction;
scheme = builder.scheme;
schemeSpecificPart = builder.schemeSpecificPart;
userInfo = builder.userInfo;
host = builder.host;
hostAddress = builder.hostAddress;
protocolVersion = builder.protocolVersion;
port = builder.port;
query = builder.query;
fragment = builder.fragment;
fatalResolveErrorsEnabled = builder.fatalResolveErrorsEnabled;
}
/** /**
* Set the character set of the URL. Default is UTF-8. * Set the character set of the URL. Default is UTF-8.
* *

View file

@ -276,6 +276,14 @@ class URLBuilderTest {
assertEquals("/foobar?a%25=b%25&c=%20d%20", url.relativeReference()); assertEquals("/foobar?a%25=b%25&c=%20d%20", url.relativeReference());
assertEquals("https://google.com:8008/foobar?a%25=b%25&c=%20d%20", url.toExternalForm()); assertEquals("https://google.com:8008/foobar?a%25=b%25&c=%20d%20", url.toExternalForm());
assertEquals("https://google.com:8008/foobar?a%=b%&c= d ", url.toString()); assertEquals("https://google.com:8008/foobar?a%=b%&c= d ", url.toString());
// test inheritance of params added by mutator
URL url1 = URL.from("http://example.com");
url1.mutator().queryParams.add("a", "b");
assertEquals("http://example.com?a=b", url1.toString());
URL url2 = URL.from(url1); // copy
url2.mutator().queryParams.add("c", "d");
assertEquals("http://example.com?a=b&c=d", url2.toString());
} }
@Test @Test

View file

@ -18,7 +18,7 @@ class URLParserTest {
@Test @Test
void testNull() { void testNull() {
assertEquals(URL.nullUrl(), URL.from(null)); assertEquals(URL.nullUrl(), URL.from((String) null));
} }
@Test @Test