use of org.jboss.resteasy.util.WeightedMediaType in project resteasy by resteasy.
the class SegmentNode method match.
public MatchCache match(List<Match> matches, String httpMethod, HttpRequest request) {
MediaType contentType = request.getHttpHeaders().getMediaType();
List<MediaType> requestAccepts = request.getHttpHeaders().getAcceptableMediaTypes();
List<WeightedMediaType> weightedAccepts = new ArrayList<WeightedMediaType>();
for (MediaType accept : requestAccepts) weightedAccepts.add(WeightedMediaType.parse(accept));
List<Match> list = new ArrayList<Match>();
boolean methodMatch = false;
boolean consumeMatch = false;
// make a list of all compatible ResourceMethods
for (Match match : matches) {
ResourceMethodInvoker invoker = (ResourceMethodInvoker) match.expression.getInvoker();
if (invoker.getHttpMethods().contains(httpMethod.toUpperCase())) {
methodMatch = true;
if (invoker.doesConsume(contentType)) {
consumeMatch = true;
if (invoker.doesProduce(weightedAccepts)) {
list.add(match);
}
}
}
}
if (list.size() == 0) {
if (!methodMatch) {
HashSet<String> allowed = new HashSet<String>();
for (Match match : matches) {
allowed.addAll(((ResourceMethodInvoker) match.expression.getInvoker()).getHttpMethods());
}
if (httpMethod.equalsIgnoreCase("HEAD") && allowed.contains("GET")) {
return match(matches, "GET", request);
}
if (allowed.contains("GET"))
allowed.add("HEAD");
allowed.add("OPTIONS");
StringBuilder allowHeaders = new StringBuilder("");
boolean first = true;
for (String allow : allowed) {
if (first)
first = false;
else
allowHeaders.append(", ");
allowHeaders.append(allow);
}
String allowHeaderValue = allowHeaders.toString();
if (httpMethod.equals("OPTIONS")) {
ResponseBuilder resBuilder = Response.ok(allowHeaderValue.toString(), MediaType.TEXT_PLAIN_TYPE).header(HttpHeaderNames.ALLOW, allowHeaderValue.toString());
if (allowed.contains("PATCH")) {
Set<MediaType> patchAccepts = new HashSet<MediaType>(8);
for (Match match : matches) {
if (((ResourceMethodInvoker) match.expression.getInvoker()).getHttpMethods().contains("PATCH")) {
patchAccepts.addAll(Arrays.asList(((ResourceMethodInvoker) match.expression.getInvoker()).getConsumes()));
}
}
StringBuilder acceptPatch = new StringBuilder("");
first = true;
for (MediaType mediaType : patchAccepts) {
if (first)
first = false;
else
acceptPatch.append(", ");
acceptPatch.append(mediaType.toString());
}
resBuilder.header(HttpHeaderNames.ACCEPT_PATCH, acceptPatch.toString());
}
throw new DefaultOptionsMethodException(Messages.MESSAGES.noResourceMethodFoundForOptions(), resBuilder.build());
} else {
Response res = Response.status(HttpResponseCodes.SC_METHOD_NOT_ALLOWED).header(HttpHeaderNames.ALLOW, allowHeaderValue).build();
throw new NotAllowedException(Messages.MESSAGES.noResourceMethodFoundForHttpMethod(httpMethod), res);
}
} else if (!consumeMatch) {
throw new NotSupportedException(Messages.MESSAGES.cannotConsumeContentType());
}
throw new NotAcceptableException(Messages.MESSAGES.noMatchForAcceptHeader());
}
// if (list.size() == 1) return list.get(0); //don't do this optimization as we need to set chosen accept
List<SortEntry> sortList = new ArrayList<SortEntry>();
for (Match match : list) {
ResourceMethodInvoker invoker = (ResourceMethodInvoker) match.expression.getInvoker();
if (contentType == null)
contentType = MediaType.WILDCARD_TYPE;
MediaType[] consumes = invoker.getConsumes();
if (consumes.length == 0) {
consumes = WILDCARD_ARRAY;
}
MediaType[] produces = invoker.getProduces();
if (produces.length == 0) {
produces = WILDCARD_ARRAY;
}
List<SortFactor> consumeCombo = new ArrayList<SortFactor>();
for (MediaType consume : consumes) {
consumeCombo.add(createSortFactor(contentType, consume));
}
for (MediaType produce : produces) {
List<MediaType> acceptableMediaTypes = requestAccepts;
if (acceptableMediaTypes.size() == 0) {
acceptableMediaTypes = DEFAULT_ACCEPTS;
}
for (MediaType accept : acceptableMediaTypes) {
if (accept.isCompatible(produce)) {
SortFactor sortFactor = createSortFactor(accept, produce);
for (SortFactor consume : consumeCombo) {
sortList.add(new SortEntry(match, consume, sortFactor, produce));
}
}
}
}
}
Collections.sort(sortList);
SortEntry sortEntry = sortList.get(0);
String[] mm = matchingMethods(sortList);
if (mm != null) {
boolean isFailFast = ConfigurationFactory.getInstance().getConfiguration().getOptionalValue(ResteasyContextParameters.RESTEASY_FAIL_FAST_ON_MULTIPLE_RESOURCES_MATCHING, boolean.class).orElse(false);
if (isFailFast) {
throw new RuntimeException(Messages.MESSAGES.multipleMethodsMatchFailFast(requestToString(request), mm));
} else {
LogMessages.LOGGER.multipleMethodsMatch(requestToString(request), mm);
}
}
MediaType acceptType = sortEntry.getAcceptType();
request.setAttribute(RESTEASY_CHOSEN_ACCEPT, acceptType);
MatchCache ctx = new MatchCache();
ctx.chosen = acceptType;
ctx.match = sortEntry.match;
ctx.invoker = sortEntry.match.expression.invoker;
return ctx;
}
Aggregations