forked from dropwizard/dropwizard
/
AbstractParam.java
135 lines (121 loc) · 4.2 KB
/
AbstractParam.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package io.dropwizard.jersey.params;
import io.dropwizard.jersey.errors.ErrorMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
/**
* An abstract base class from which to build Jersey parameter classes.
*
* @param <T> the type of value wrapped by the parameter
*/
public abstract class AbstractParam<T> {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractParam.class);
private final String parameterName;
private final T value;
protected AbstractParam(String input) {
this(input, "Parameter");
}
/**
* Given an input value from a client, creates a parameter wrapping its parsed value.
*
* @param input an input value from a client request
*/
@SuppressWarnings({"AbstractMethodCallInConstructor", "OverriddenMethodCallDuringObjectConstruction"})
protected AbstractParam(String input, String parameterName) {
this.parameterName = parameterName;
try {
this.value = parse(input);
} catch (Exception e) {
throw new WebApplicationException(error(input, e));
}
}
/**
* Given a string representation which was unable to be parsed and the exception thrown, produce
* a {@link Response} to be sent to the client.
*
* By default, generates a {@code 400 Bad Request} with a plain text entity generated by
* {@link #errorMessage(Exception)}.
*
* @param input the raw input value
* @param e the exception thrown while parsing {@code input}
* @return the {@link Response} to be sent to the client
*/
protected Response error(String input, Exception e) {
LOGGER.debug("Invalid input received: {}", input);
String errorMessage = errorMessage(e);
if (errorMessage.contains("%s")) {
errorMessage = String.format(errorMessage, parameterName);
}
return Response.status(getErrorStatus())
.entity(new ErrorMessage(getErrorStatus().getStatusCode(),
errorMessage))
.type(mediaType())
.build();
}
/**
* Returns the media type of the error message entity.
*
* @return the media type of the error message entity
*/
protected MediaType mediaType() {
return MediaType.APPLICATION_JSON_TYPE;
}
/**
* Given a string representation which was unable to be parsed and the exception thrown, produce
* an entity to be sent to the client.
*
* @param e the exception thrown while parsing {@code input}
* @return the error message to be sent the client
*/
protected String errorMessage(Exception e) {
return String.format("%s is invalid: %s", parameterName, e.getMessage());
}
/**
* Given a string representation which was unable to be parsed, produce a {@link Status} for the
* {@link Response} to be sent to the client.
*
* @return the HTTP {@link Status} of the error message
*/
@SuppressWarnings("MethodMayBeStatic")
protected Status getErrorStatus() {
return Status.BAD_REQUEST;
}
/**
* Given a string representation, parse it and return an instance of the parameter type.
*
* @param input the raw input
* @return {@code input}, parsed as an instance of {@code T}
* @throws Exception if there is an error parsing the input
*/
protected abstract T parse(String input) throws Exception;
/**
* Returns the underlying value.
*
* @return the underlying value
*/
public T get() {
return value;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if ((obj == null) || (getClass() != obj.getClass())) {
return false;
}
final AbstractParam<?> that = (AbstractParam<?>) obj;
return value.equals(that.value);
}
@Override
public int hashCode() {
return value.hashCode();
}
@Override
public String toString() {
return value.toString();
}
}