diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java index fe1e3ede..df696649 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java @@ -64,7 +64,7 @@ public class Account extends AcmeJsonResource { * {@code null} if the server did not provide such an information. */ public Boolean getTermsOfServiceAgreed() { - return getJSON().get(KEY_TOS_AGREED).optional().map(Value::asBoolean).orElse(null); + return getJSON().get(KEY_TOS_AGREED).map(Value::asBoolean).orElse(null); } /** @@ -85,7 +85,7 @@ public class Account extends AcmeJsonResource { * {@link Status#REVOKED}. */ public Status getStatus() { - return getJSON().get(KEY_STATUS).asStatusOrElse(Status.UNKNOWN); + return getJSON().get(KEY_STATUS).asStatus(); } /** diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Authorization.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Authorization.java index 58010aa1..87275f4e 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Authorization.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Authorization.java @@ -50,12 +50,12 @@ public class Authorization extends AcmeJsonResource { * order, check the {@link #isWildcard()} method. */ public String getDomain() { - JSON jsonIdentifier = getJSON().get("identifier").required().asObject(); - String type = jsonIdentifier.get("type").required().asString(); + JSON jsonIdentifier = getJSON().get("identifier").asObject(); + String type = jsonIdentifier.get("type").asString(); if (!"dns".equals(type)) { throw new AcmeProtocolException("Unknown authorization type: " + type); } - return jsonIdentifier.get("value").required().asString(); + return jsonIdentifier.get("value").asString(); } /** @@ -65,14 +65,14 @@ public class Authorization extends AcmeJsonResource { * {@link Status#INVALID}, {@link Status#DEACTIVATED}, {@link Status#REVOKED}. */ public Status getStatus() { - return getJSON().get("status").asStatusOrElse(Status.UNKNOWN); + return getJSON().get("status").asStatus(); } /** * Gets the expiry date of the authorization, if set by the server. */ public Instant getExpires() { - return getJSON().get("expires").optional() + return getJSON().get("expires") .map(Value::asString) .map(AcmeUtils::parseTimestamp) .orElse(null); @@ -83,7 +83,7 @@ public class Authorization extends AcmeJsonResource { * {@code false} otherwise. */ public boolean isWildcard() { - return getJSON().get("wildcard").optional() + return getJSON().get("wildcard") .map(Value::asBoolean) .orElse(false); } diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Metadata.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Metadata.java index a4005a13..25e761fa 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Metadata.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Metadata.java @@ -44,7 +44,7 @@ public class Metadata { * available. */ public URI getTermsOfService() { - return meta.get("termsOfService").asURI(); + return meta.get("termsOfService").map(Value::asURI).orElse(null); } /** @@ -52,7 +52,7 @@ public class Metadata { * server. {@code null} if not available. */ public URL getWebsite() { - return meta.get("website").asURL(); + return meta.get("website").map(Value::asURL).orElse(null); } /** @@ -60,7 +60,9 @@ public class Metadata { * itself for the purposes of CAA record validation. Empty if not available. */ public Collection getCaaIdentities() { - return meta.get("caaIdentities").asArray().stream() + return meta.get("caaIdentities") + .asArray() + .stream() .map(Value::asString) .collect(toList()); } @@ -69,7 +71,7 @@ public class Metadata { * Returns whether an external account is required by this CA. */ public boolean isExternalAccountRequired() { - return meta.get("externalAccountRequired").orElse(false).asBoolean(); + return meta.get("externalAccountRequired").map(Value::asBoolean).orElse(false); } /** diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Order.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Order.java index 9583ae8e..ecc4cfeb 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Order.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Order.java @@ -45,21 +45,21 @@ public class Order extends AcmeJsonResource { * {@link Status#PROCESSING}, {@link Status#VALID}, {@link Status#INVALID}. */ public Status getStatus() { - return getJSON().get("status").asStatusOrElse(Status.UNKNOWN); + return getJSON().get("status").asStatus(); } /** * Returns a {@link Problem} document if the order failed. */ public Problem getError() { - return getJSON().get("error").asProblem(getLocation()); + return getJSON().get("error").map(v -> v.asProblem(getLocation())).orElse(null); } /** * Gets the expiry date of the authorization, if set by the server. */ public Instant getExpires() { - return getJSON().get("expires").asInstant(); + return getJSON().get("expires").map(Value::asInstant).orElse(null); } /** @@ -78,14 +78,14 @@ public class Order extends AcmeJsonResource { * Gets the "not before" date that was used for the order, or {@code null}. */ public Instant getNotBefore() { - return getJSON().get("notBefore").asInstant(); + return getJSON().get("notBefore").map(Value::asInstant).orElse(null); } /** * Gets the "not after" date that was used for the order, or {@code null}. */ public Instant getNotAfter() { - return getJSON().get("notAfter").asInstant(); + return getJSON().get("notAfter").map(Value::asInstant).orElse(null); } /** @@ -114,7 +114,7 @@ public class Order extends AcmeJsonResource { * Gets the {@link Certificate} if it is available. {@code null} otherwise. */ public Certificate getCertificate() { - return getJSON().get("certificate").optional() + return getJSON().get("certificate") .map(Value::asURL) .map(getLogin()::bindCertificate) .orElse(null); diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java index 8e79d0ae..9b93fd14 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java @@ -24,6 +24,7 @@ import java.util.List; import org.shredzone.acme4j.exception.AcmeProtocolException; import org.shredzone.acme4j.toolbox.JSON; +import org.shredzone.acme4j.toolbox.JSON.Value; /** * Represents a JSON Problem. @@ -53,12 +54,16 @@ public class Problem implements Serializable { * Returns the problem type. It is always an absolute URI. */ public URI getType() { - try { - String type = problemJson.get("type").asString(); - return type != null ? baseUrl.toURI().resolve(type) : null; - } catch (URISyntaxException ex) { - throw new IllegalArgumentException("Bad base URL", ex); - } + return problemJson.get("type") + .map(Value::asString) + .map(it -> { + try { + return baseUrl.toURI().resolve(it); + } catch (URISyntaxException ex) { + throw new IllegalArgumentException("Bad base URL", ex); + } + }) + .orElse(null); } /** @@ -68,7 +73,7 @@ public class Problem implements Serializable { * @see #toString() */ public String getTitle() { - return problemJson.get("title").asString(); + return problemJson.get("title").map(Value::asString).orElse(null); } /** @@ -78,7 +83,7 @@ public class Problem implements Serializable { * @see #toString() */ public String getDetail() { - return problemJson.get("detail").asString(); + return problemJson.get("detail").map(Value::asString).orElse(null); } /** @@ -86,29 +91,35 @@ public class Problem implements Serializable { * an absolute URI. */ public URI getInstance() { - try { - String instance = problemJson.get("instance").asString(); - return instance != null ? baseUrl.toURI().resolve(instance) : null; - } catch (URISyntaxException ex) { - throw new IllegalArgumentException("Bad base URL", ex); - } + return problemJson.get("instance") + .map(Value::asString) + .map(it -> { + try { + return baseUrl.toURI().resolve(it); + } catch (URISyntaxException ex) { + throw new IllegalArgumentException("Bad base URL", ex); + } + }) + .orElse(null); } /** * Returns the domain this problem relates to. May be {@code null}. */ public String getDomain() { - JSON identifier = problemJson.get("identifier").asObject(); - if (identifier == null) { + Value identifier = problemJson.get("identifier"); + if (!identifier.isPresent()) { return null; } - String type = identifier.get("type").asString(); + JSON json = identifier.asObject(); + + String type = json.get("type").asString(); if (!"dns".equals(type)) { throw new AcmeProtocolException("Cannot process a " + type + " identifier"); } - return identifier.get("value").asString(); + return json.get("value").asString(); } /** @@ -117,7 +128,8 @@ public class Problem implements Serializable { public List getSubProblems() { return unmodifiableList( problemJson.get("subproblems") - .asArray().stream() + .asArray() + .stream() .map(o -> o.asProblem(baseUrl)) .collect(toList()) ); diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Session.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Session.java index 34231e93..0e520f77 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Session.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Session.java @@ -31,6 +31,7 @@ import org.shredzone.acme4j.connector.Resource; import org.shredzone.acme4j.exception.AcmeException; import org.shredzone.acme4j.provider.AcmeProvider; import org.shredzone.acme4j.toolbox.JSON; +import org.shredzone.acme4j.toolbox.JSON.Value; /** * A session stores the ACME server URI. It also tracks communication parameters. @@ -193,19 +194,18 @@ public class Session { JSON directoryJson = provider().directory(this, getServerUri()); - JSON meta = directoryJson.get("meta").asObject(); - if (meta != null) { - metadata.set(new Metadata(meta)); + Value meta = directoryJson.get("meta"); + if (meta.isPresent()) { + metadata.set(new Metadata(meta.asObject())); } else { metadata.set(new Metadata(JSON.empty())); } Map map = new EnumMap<>(Resource.class); for (Resource res : Resource.values()) { - URL url = directoryJson.get(res.path()).asURL(); - if (url != null) { - map.put(res, url); - } + directoryJson.get(res.path()) + .map(Value::asURL) + .ifPresent(url -> map.put(res, url)); } resourceMap.set(map); diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Challenge.java b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Challenge.java index a2787513..967b1617 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Challenge.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Challenge.java @@ -23,6 +23,7 @@ import org.shredzone.acme4j.connector.Connection; import org.shredzone.acme4j.exception.AcmeException; import org.shredzone.acme4j.exception.AcmeProtocolException; import org.shredzone.acme4j.toolbox.JSON; +import org.shredzone.acme4j.toolbox.JSON.Value; import org.shredzone.acme4j.toolbox.JSONBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,7 +56,7 @@ public class Challenge extends AcmeJsonResource { * {@link JSON} challenge data */ public Challenge(Login login, JSON data) { - super(login, data.get(KEY_URL).required().asURL()); + super(login, data.get(KEY_URL).asURL()); setJSON(data); } @@ -73,14 +74,14 @@ public class Challenge extends AcmeJsonResource { * {@link Status#VALID}, {@link Status#INVALID}. */ public Status getStatus() { - return getJSON().get(KEY_STATUS).asStatusOrElse(Status.UNKNOWN); + return getJSON().get(KEY_STATUS).asStatus(); } /** * Returns the validation date, if returned by the server. */ public Instant getValidated() { - return getJSON().get(KEY_VALIDATED).asInstant(); + return getJSON().get(KEY_VALIDATED).map(Value::asInstant).orElse(null); } /** @@ -89,7 +90,9 @@ public class Challenge extends AcmeJsonResource { * {@link Problem#getSubProblems()}. */ public Problem getError() { - return getJSON().get(KEY_ERROR).asProblem(getLocation()); + return getJSON().get(KEY_ERROR) + .map(it -> it.asProblem(getLocation())) + .orElse(null); } /** @@ -115,13 +118,13 @@ public class Challenge extends AcmeJsonResource { @Override protected void setJSON(JSON json) { - String type = json.get(KEY_TYPE).required().asString(); + String type = json.get(KEY_TYPE).asString(); if (!acceptable(type)) { throw new AcmeProtocolException("incompatible type " + type + " for this challenge"); } - String loc = json.get(KEY_URL).required().asString(); + String loc = json.get(KEY_URL).asString(); if (loc != null && !loc.equals(getLocation().toString())) { throw new AcmeProtocolException("challenge has changed its location"); } diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TokenChallenge.java b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TokenChallenge.java index 12dda0b1..8d7d89af 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TokenChallenge.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TokenChallenge.java @@ -56,7 +56,7 @@ public class TokenChallenge extends Challenge { * Gets the token. */ protected String getToken() { - return getJSON().get(KEY_TOKEN).required().asString(); + return getJSON().get(KEY_TOKEN).asString(); } /** diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AbstractAcmeProvider.java b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AbstractAcmeProvider.java index 361bfea7..86812d9f 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AbstractAcmeProvider.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AbstractAcmeProvider.java @@ -86,7 +86,7 @@ public abstract class AbstractAcmeProvider implements AcmeProvider { Objects.requireNonNull(login, "login"); Objects.requireNonNull(data, "data"); - String type = data.get("type").required().asString(); + String type = data.get("type").asString(); BiFunction constructor = CHALLENGES.get(type); if (constructor != null) { diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java index 6fb5aaab..6a125585 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java @@ -37,6 +37,7 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -247,6 +248,9 @@ public final class JSON implements Serializable { /** * A single JSON value. This instance also covers {@code null} values. + *

+ * All return values are never {@code null} unless specified otherwise. For optional + * parameters, use {@link Value#optional()}. */ public static final class Value { private final String path; @@ -265,58 +269,53 @@ public final class JSON implements Serializable { this.val = val; } + /** + * Checks if this value is {@code null}. + * + * @return {@code true} if this value is present, {@code false} if {@code null}. + */ + public boolean isPresent() { + return val != null; + } + /** * Returns this value as {@link Optional}, for further mapping and filtering. * * @return {@link Optional} of this value, or {@link Optional#empty()} if this * value is {@code null}. + * @see #map(Function) */ public Optional optional() { return val != null ? Optional.of(this) : Optional.empty(); } /** - * Checks if the value is present. An {@link AcmeProtocolException} is thrown if - * the value is {@code null}. + * Returns this value as an {@link Optional} of the desired type, for further + * mapping and filtering. * - * @return itself + * @param mapper + * A {@link Function} that converts a {@link Value} to the desired type + * @return {@link Optional} of this value, or {@link Optional#empty()} if this + * value is {@code null}. + * @see #optional() */ - public Value required() { - if (val == null) { - throw new AcmeProtocolException(path + ": required, but not set"); - } - return this; - } - - /** - * Checks if the value is present. If not, the default value is used instead. - * - * @param def Default value - * @return itself - */ - public Value orElse(Object def) { - return val != null ? this : new Value(path, def); + public Optional map(Function mapper) { + return optional().map(mapper); } /** * Returns the value as {@link String}. - * - * @return {@link String}, or {@code null} if the value was not set. */ public String asString() { - return val != null ? val.toString() : null; + required(); + return val.toString(); } /** * Returns the value as JSON object. - * - * @return {@link JSON}, or {@code null} if the value was not set. */ public JSON asObject() { - if (val == null) { - return null; - } - + required(); try { return new JSON(path, (Map) val); } catch (ClassCastException ex) { @@ -329,20 +328,17 @@ public final class JSON implements Serializable { * * @param baseUrl * Base {@link URL} to resolve relative links against - * @return {@link Problem}, or {@code null} if the value was not set. */ public Problem asProblem(URL baseUrl) { - if (val == null) { - return null; - } - + required(); return new Problem(asObject(), baseUrl); } /** - * Returns the value as JSON array. - * - * @return {@link JSON.Array}, which is empty if the value was not set. + * Returns the value as {@link JSON.Array}. + *

+ * Unlike the other getters, this method returns an empty array if the value is + * not set. Use {@link #isPresent()} to find out if the value was actually set. */ public Array asArray() { if (val == null) { @@ -358,12 +354,9 @@ public final class JSON implements Serializable { /** * Returns the value as int. - * - * @return integer value */ public int asInt() { required(); - try { return ((Number) val).intValue(); } catch (ClassCastException ex) { @@ -373,12 +366,9 @@ public final class JSON implements Serializable { /** * Returns the value as boolean. - * - * @return integer value */ public boolean asBoolean() { required(); - try { return (Boolean) val; } catch (ClassCastException ex) { @@ -388,14 +378,9 @@ public final class JSON implements Serializable { /** * Returns the value as {@link URI}. - * - * @return {@link URI}, or {@code null} if the value was not set. */ public URI asURI() { - if (val == null) { - return null; - } - + required(); try { return new URI(val.toString()); } catch (URISyntaxException ex) { @@ -405,14 +390,9 @@ public final class JSON implements Serializable { /** * Returns the value as {@link URL}. - * - * @return {@link URL}, or {@code null} if the value was not set. */ public URL asURL() { - if (val == null) { - return null; - } - + required(); try { return new URL(val.toString()); } catch (MalformedURLException ex) { @@ -422,14 +402,9 @@ public final class JSON implements Serializable { /** * Returns the value as {@link Instant}. - * - * @return {@link Instant}, or {@code null} if the value was not set. */ public Instant asInstant() { - if (val == null) { - return null; - } - + required(); try { return parseTimestamp(val.toString()); } catch (IllegalArgumentException ex) { @@ -439,32 +414,30 @@ public final class JSON implements Serializable { /** * Returns the value as base64 decoded byte array. - * - * @return byte array, or {@code null} if the value was not set. */ public byte[] asBinary() { - if (val == null) { - return null; //NOSONAR: we want to return null here - } - + required(); return AcmeUtils.base64UrlDecode(val.toString()); } /** - * Returns the parsed status. - * - * @param def - * Default status if value is not present or {@code null} - * @return {@link Status} + * Returns the parsed {@link Status}. */ - public Status asStatusOrElse(Status def) { - if (val == null) { - return def; - } - + public Status asStatus() { + required(); return Status.parse(val.toString()); } + /** + * Checks if the value is present. An {@link AcmeProtocolException} is thrown if + * the value is {@code null}. + */ + private void required() { + if (!isPresent()) { + throw new AcmeProtocolException(path + ": required, but not set"); + } + } + @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof Value)) { diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountBuilderTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountBuilderTest.java index 1621c205..0803e5b7 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountBuilderTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountBuilderTest.java @@ -121,7 +121,6 @@ public class AccountBuilderTest { JSON binding = claims.toJSON() .get("externalAccountBinding") - .required() .asObject(); String encodedHeader = binding.get("protected").asString(); diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/challenge/ChallengeTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/challenge/ChallengeTest.java index 08cb236e..e8341598 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/challenge/ChallengeTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/challenge/ChallengeTest.java @@ -60,8 +60,6 @@ public class ChallengeTest { assertThat(challenge.getValidated(), is(parseTimestamp("2015-12-12T17:19:36.336785823Z"))); assertThat(challenge.getJSON().get("type").asString(), is("generic-01")); assertThat(challenge.getJSON().get("url").asURL(), is(url("http://example.com/challenge/123"))); - assertThat(challenge.getJSON().get("notPresent").asString(), is(nullValue())); - assertThat(challenge.getJSON().get("notPresentUrl").asURL(), is(nullValue())); Problem error = challenge.getError(); assertThat(error, is(notNullValue())); diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/JSONTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/JSONTest.java index 6b495182..49473c18 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/JSONTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/JSONTest.java @@ -40,6 +40,7 @@ import org.junit.Test; import org.shredzone.acme4j.Problem; import org.shredzone.acme4j.Status; import org.shredzone.acme4j.exception.AcmeProtocolException; +import org.shredzone.acme4j.toolbox.JSON.Value; /** * Unit test for {@link JSON}. @@ -198,10 +199,12 @@ public class JSONTest { assertThat(json.get("uri").asURI(), is(URI.create("mailto:foo@example.com"))); assertThat(json.get("url").asURL(), is(url("http://example.com"))); assertThat(json.get("date").asInstant(), is(date)); - assertThat(json.get("status").asStatusOrElse(Status.INVALID), is(Status.VALID)); + assertThat(json.get("status").asStatus(), is(Status.VALID)); assertThat(json.get("binary").asBinary(), is("Chainsaw".getBytes())); + assertThat(json.get("text").isPresent(), is(true)); assertThat(json.get("text").optional().isPresent(), is(true)); + assertThat(json.get("text").map(Value::asString).isPresent(), is(true)); JSON.Array array = json.get("array").asArray(); assertThat(array.get(0).asString(), is("foo")); @@ -230,20 +233,65 @@ public class JSONTest { JSON json = TestUtils.getJSON("datatypes"); assertThat(json.get("none"), is(notNullValue())); - assertThat(json.get("none").asString(), is(nullValue())); - assertThat(json.get("none").asURI(), is(nullValue())); - assertThat(json.get("none").asURL(), is(nullValue())); - assertThat(json.get("none").asInstant(), is(nullValue())); - assertThat(json.get("none").asObject(), is(nullValue())); - assertThat(json.get("none").asStatusOrElse(Status.INVALID), is(Status.INVALID)); - assertThat(json.get("none").asBinary(), is(nullValue())); - assertThat(json.get("none").asProblem(BASE_URL), is(nullValue())); - - assertThat(json.get("none").orElse("foo").asString(), is("foo")); - assertThat(json.get("none").orElse(42).asInt(), is(42)); - assertThat(json.get("none").orElse(true).asBoolean(), is(true)); - + assertThat(json.get("none").isPresent(), is(false)); assertThat(json.get("none").optional().isPresent(), is(false)); + assertThat(json.get("none").map(Value::asString).isPresent(), is(false)); + + try { + json.get("none").asString(); + fail("asString did not fail"); + } catch (AcmeProtocolException ex) { + // expected + } + + try { + json.get("none").asURI(); + fail("asURI did not fail"); + } catch (AcmeProtocolException ex) { + // expected + } + + try { + json.get("none").asURL(); + fail("asURL did not fail"); + } catch (AcmeProtocolException ex) { + // expected + } + + try { + json.get("none").asInstant(); + fail("asInstant did not fail"); + } catch (AcmeProtocolException ex) { + // expected + } + + try { + json.get("none").asObject(); + fail("asObject did not fail"); + } catch (AcmeProtocolException ex) { + // expected + } + + try { + json.get("none").asStatus(); + fail("asStatus did not fail"); + } catch (AcmeProtocolException ex) { + // expected + } + + try { + json.get("none").asBinary(); + fail("asBinary did not fail"); + } catch (AcmeProtocolException ex) { + // expected + } + + try { + json.get("none").asProblem(BASE_URL); + fail("asProblem did not fail"); + } catch (AcmeProtocolException ex) { + // expected + } try { json.get("none").asInt(); @@ -258,16 +306,6 @@ public class JSONTest { } catch (AcmeProtocolException ex) { // expected } - - try { - json.get("none").required(); - fail("required did not fail"); - } catch (AcmeProtocolException ex) { - // expected - } - - JSON.Value textv = json.get("text"); - assertThat(textv.required(), is(textv)); } /**