1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.web.servlet.mvc.condition;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Set;
26 import javax.servlet.http.HttpServletRequest;
27
28 import org.springframework.http.InvalidMediaTypeException;
29 import org.springframework.http.MediaType;
30 import org.springframework.util.StringUtils;
31 import org.springframework.web.HttpMediaTypeNotSupportedException;
32 import org.springframework.web.bind.annotation.RequestMapping;
33 import org.springframework.web.servlet.mvc.condition.HeadersRequestCondition.HeaderExpression;
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public final class ConsumesRequestCondition extends AbstractRequestCondition<ConsumesRequestCondition> {
48
49 private final List<ConsumeMediaTypeExpression> expressions;
50
51
52
53
54
55
56
57
58 public ConsumesRequestCondition(String... consumes) {
59 this(consumes, null);
60 }
61
62
63
64
65
66
67
68
69
70 public ConsumesRequestCondition(String[] consumes, String[] headers) {
71 this(parseExpressions(consumes, headers));
72 }
73
74
75
76
77 private ConsumesRequestCondition(Collection<ConsumeMediaTypeExpression> expressions) {
78 this.expressions = new ArrayList<ConsumeMediaTypeExpression>(expressions);
79 Collections.sort(this.expressions);
80 }
81
82
83 private static Set<ConsumeMediaTypeExpression> parseExpressions(String[] consumes, String[] headers) {
84 Set<ConsumeMediaTypeExpression> result = new LinkedHashSet<ConsumeMediaTypeExpression>();
85 if (headers != null) {
86 for (String header : headers) {
87 HeaderExpression expr = new HeaderExpression(header);
88 if ("Content-Type".equalsIgnoreCase(expr.name)) {
89 for (MediaType mediaType : MediaType.parseMediaTypes(expr.value)) {
90 result.add(new ConsumeMediaTypeExpression(mediaType, expr.isNegated));
91 }
92 }
93 }
94 }
95 if (consumes != null) {
96 for (String consume : consumes) {
97 result.add(new ConsumeMediaTypeExpression(consume));
98 }
99 }
100 return result;
101 }
102
103
104
105
106
107 public Set<MediaTypeExpression> getExpressions() {
108 return new LinkedHashSet<MediaTypeExpression>(this.expressions);
109 }
110
111
112
113
114 public Set<MediaType> getConsumableMediaTypes() {
115 Set<MediaType> result = new LinkedHashSet<MediaType>();
116 for (ConsumeMediaTypeExpression expression : this.expressions) {
117 if (!expression.isNegated()) {
118 result.add(expression.getMediaType());
119 }
120 }
121 return result;
122 }
123
124
125
126
127 public boolean isEmpty() {
128 return this.expressions.isEmpty();
129 }
130
131 @Override
132 protected Collection<ConsumeMediaTypeExpression> getContent() {
133 return this.expressions;
134 }
135
136 @Override
137 protected String getToStringInfix() {
138 return " || ";
139 }
140
141
142
143
144
145
146 @Override
147 public ConsumesRequestCondition combine(ConsumesRequestCondition other) {
148 return !other.expressions.isEmpty() ? other : this;
149 }
150
151
152
153
154
155
156
157
158
159
160
161 @Override
162 public ConsumesRequestCondition getMatchingCondition(HttpServletRequest request) {
163 if (isEmpty()) {
164 return this;
165 }
166 Set<ConsumeMediaTypeExpression> result = new LinkedHashSet<ConsumeMediaTypeExpression>(expressions);
167 for (Iterator<ConsumeMediaTypeExpression> iterator = result.iterator(); iterator.hasNext();) {
168 ConsumeMediaTypeExpression expression = iterator.next();
169 if (!expression.match(request)) {
170 iterator.remove();
171 }
172 }
173 return (result.isEmpty()) ? null : new ConsumesRequestCondition(result);
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187 @Override
188 public int compareTo(ConsumesRequestCondition other, HttpServletRequest request) {
189 if (this.expressions.isEmpty() && other.expressions.isEmpty()) {
190 return 0;
191 }
192 else if (this.expressions.isEmpty()) {
193 return 1;
194 }
195 else if (other.expressions.isEmpty()) {
196 return -1;
197 }
198 else {
199 return this.expressions.get(0).compareTo(other.expressions.get(0));
200 }
201 }
202
203
204
205
206
207 static class ConsumeMediaTypeExpression extends AbstractMediaTypeExpression {
208
209 ConsumeMediaTypeExpression(String expression) {
210 super(expression);
211 }
212
213 ConsumeMediaTypeExpression(MediaType mediaType, boolean negated) {
214 super(mediaType, negated);
215 }
216
217 @Override
218 protected boolean matchMediaType(HttpServletRequest request) throws HttpMediaTypeNotSupportedException {
219 try {
220 MediaType contentType = StringUtils.hasLength(request.getContentType()) ?
221 MediaType.parseMediaType(request.getContentType()) :
222 MediaType.APPLICATION_OCTET_STREAM;
223 return getMediaType().includes(contentType);
224 }
225 catch (InvalidMediaTypeException ex) {
226 throw new HttpMediaTypeNotSupportedException(
227 "Can't parse Content-Type [" + request.getContentType() + "]: " + ex.getMessage());
228 }
229 }
230 }
231
232 }