package net.hamnaberg.json;
import javaslang.control.Option;
import net.hamnaberg.json.util.Iterables;
import net.hamnaberg.json.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;
public final class URITarget implements Target {
private URI href;
public URITarget(String href) {
this(URI.create(href));
}
public URITarget(URI href) {
this.href = href;
}
@Override
public boolean isURITemplate() {
return false;
}
public URI toURI() {
return href;
}
public URI expand(Iterable<Property> properties) {
if (Iterables.isEmpty(properties)) {
return href;
}
final String query = href.getQuery();
StringBuilder fromProperties = buildQuery(properties);
if (StringUtils.isNotBlank(query)) {
String actual = query;
if (fromProperties.length() > 0) {
actual = query + "&";
}
fromProperties.insert(0, actual);
}
String str = href.toString();
int queryPart = str.indexOf('?');
if (queryPart > 0) {
str = str.substring(0, queryPart);
}
String createdQuery = fromProperties.length() == 0 ? "" : ( "?" + fromProperties.toString());
return URI.create(str + createdQuery);
}
private StringBuilder buildQuery(Iterable<Property> properties) {
StringBuilder sb = new StringBuilder();
for (Property property : properties) {
if (property.hasObject()) {
throw new IllegalArgumentException("Expanding Cj Property object is undefined in the spec.");
}
else {
if (property.hasArray()) {
List<Value> prop = property.getArray();
for (Value value : prop) {
if (sb.length() > 0) {
sb.append("&");
}
sb.append(property.getName()).append("=").append(encode(value.asString()));
}
}
else {
Option<Value> value = property.getValue();
if (value.isDefined()) {
if (sb.length() > 0) {
sb.append("&");
}
sb.append(property.getName()).append("=").append(encode(value.get().asString()));
}
}
}
}
return sb;
}
private String encode(String param) {
try {
return URLEncoder.encode(param, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new UnsupportedCharsetException("UTF-8");
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
URITarget uriTarget = (URITarget) o;
if (href != null ? !href.equals(uriTarget.href) : uriTarget.href != null) return false;
return true;
}
@Override
public int hashCode() {
return href != null ? href.hashCode() : 0;
}
@Override
public String toString() {
return href.toString();
}
}