Skip to content

Commit

Permalink
Used hash-based lookup rather than linear search
Browse files Browse the repository at this point in the history
  • Loading branch information
whiskeysierra committed May 27, 2019
1 parent f29e0b0 commit 6e4f8aa
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apiguardian.api.API;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -88,7 +89,7 @@ private static <E extends Enum & StatusType> Map<Integer, StatusType> buildIndex
}
}

return index;
return Collections.unmodifiableMap(index);
}

public ProblemModule withStackTraces() {
Expand Down
44 changes: 30 additions & 14 deletions problem/src/main/java/org/zalando/problem/Status.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
import org.apiguardian.api.API;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;

import static java.util.function.Function.identity;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toMap;
import static org.apiguardian.api.API.Status.MAINTAINED;

/**
Expand Down Expand Up @@ -261,6 +267,12 @@ public enum Status implements StatusType {
* @see <a href="http://tools.ietf.org/html/rfc6585#section-6">Additional HTTP Status Codes</a>
*/
NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");

private static final Map<Integer, Status> STATUSES = Arrays.stream(values())
.collect(collectingAndThen(
toMap(Status::getStatusCode, identity()),
Collections::unmodifiableMap));

private final int code;
private final String reason;

Expand All @@ -269,20 +281,6 @@ public enum Status implements StatusType {
this.reason = reasonPhrase;
}

/**
* Creates a Status instance from the given code.
*
* @param code the HTTP code as a number
* @return the correct enum value for this status code.
* @throws IllegalArgumentException if the given code does not correspond to a known HTTP status.
*/
public static Status ofCode(int code) {
return Arrays.stream(Status.values())
.filter(status -> status.getStatusCode() == code)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("There is no known status for this code (" + code + ")."));
}

/**
* Get the associated status code.
*
Expand Down Expand Up @@ -313,4 +311,22 @@ public String getReasonPhrase() {
public String toString() {
return getStatusCode() + " " + getReasonPhrase();
}

/**
* Creates a Status instance from the given code.
*
* @param code the HTTP code as a number
* @return the correct enum value for this status code.
* @throws IllegalArgumentException if the given code does not correspond to a known HTTP status.
*/
public static Status valueOf(final int code) {
@Nullable final Status status = STATUSES.get(code);

if (status == null) {
throw new IllegalArgumentException("There is no known status for this code (" + code + ").");
}

return status;
}

}
21 changes: 9 additions & 12 deletions problem/src/test/java/org/zalando/problem/StatusTest.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package org.zalando.problem;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import java.util.stream.Stream;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.emptyOrNullString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hobsoft.hamcrest.compose.ComposeMatchers.hasFeature;
import static org.junit.jupiter.api.Assertions.assertThrows;


final class StatusTest {
Expand All @@ -25,9 +25,7 @@ void shouldHaveReasonPhrase() {

@Test
void shouldHaveMeaningfulToString() {
Status notFound = Status.NOT_FOUND;

assertThat(notFound.toString(), equalTo("404 Not Found"));
assertThat(Status.NOT_FOUND.toString(), equalTo("404 Not Found"));
}

@ParameterizedTest
Expand All @@ -37,17 +35,16 @@ void shouldHaveMeaningfulToString() {
"200, OK",
"500, Internal Server Error"
})
void shouldHaveCorrectValueFromCode(int code, String line) {
Status statusFromCode = Status.ofCode(code);
void shouldHaveCorrectValueFromCode(final int statusCode, final String reasonPhrase) {
final Status status = Status.valueOf(statusCode);

assertThat(statusFromCode.getStatusCode(), equalTo(code));
assertThat(statusFromCode.getReasonPhrase(), equalTo(line));
assertThat(status.getStatusCode(), equalTo(statusCode));
assertThat(status.getReasonPhrase(), equalTo(reasonPhrase));
}

@Test
void shouldThrowOnNonExistingCode() {
Assertions.assertThrows(IllegalArgumentException.class, () -> {
Status.ofCode(111);
});
assertThrows(IllegalArgumentException.class, () -> Status.valueOf(111));
}

}

0 comments on commit 6e4f8aa

Please sign in to comment.