/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.core.impl; import org.everrest.core.impl.header.AcceptLanguage; import org.everrest.core.impl.header.AcceptMediaType; import org.everrest.core.impl.header.AcceptToken; import org.everrest.core.impl.header.Language; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Variant; import java.util.ArrayList; import java.util.List; import static java.util.stream.Collectors.toList; import static javax.ws.rs.core.HttpHeaders.ACCEPT; import static javax.ws.rs.core.HttpHeaders.ACCEPT_CHARSET; import static javax.ws.rs.core.HttpHeaders.ACCEPT_ENCODING; import static javax.ws.rs.core.HttpHeaders.ACCEPT_LANGUAGE; import static org.everrest.core.impl.header.HeaderHelper.convertToString; import static org.everrest.core.impl.header.HeaderHelper.createAcceptMediaTypeList; import static org.everrest.core.impl.header.HeaderHelper.createAcceptedCharsetList; import static org.everrest.core.impl.header.HeaderHelper.createAcceptedEncodingList; import static org.everrest.core.impl.header.HeaderHelper.createAcceptedLanguageList; public class VariantsHandler { /** * Looking for most acceptable variant for given request. * * @param request * see {@link ContainerRequest} * @param variants * see {@link Variant} and {@link VariantListBuilderImpl} * @return variant or null */ public Variant handleVariants(ContainerRequest request, List<Variant> variants) { List<AcceptMediaType> acceptMediaTypes = createAcceptMediaTypeList(convertToString(request.getRequestHeader(ACCEPT))); List<AcceptLanguage> acceptLanguages = createAcceptedLanguageList(convertToString(request.getRequestHeader(ACCEPT_LANGUAGE))); List<AcceptToken> acceptCharset = createAcceptedCharsetList(convertToString(request.getRequestHeader(ACCEPT_CHARSET))); List<AcceptToken> acceptEncoding = createAcceptedEncodingList(convertToString(request.getRequestHeader(ACCEPT_ENCODING))); List<Variant> filteredVariants = new ArrayList<>(variants); filteredVariants = filterByMediaType(acceptMediaTypes, filteredVariants); filteredVariants = filterByLanguage(acceptLanguages, filteredVariants); filteredVariants = filterByCharset(acceptCharset, filteredVariants); filteredVariants = filterByEncoding(acceptEncoding, filteredVariants); return filteredVariants.isEmpty() ? null : filteredVariants.get(0); } private List<Variant> filterByMediaType(List<AcceptMediaType> acceptMediaTypes, List<Variant> variants) { List<Variant> filteredVariants = new ArrayList<>(); acceptMediaTypes.forEach(acceptMediaType -> variants.forEach( variant -> { if (variant.getMediaType() != null && acceptMediaType.isCompatible(variant.getMediaType())) { filteredVariants.add(variant); } })); filteredVariants.addAll(variants.stream().filter(variant -> variant.getMediaType() == null).collect(toList())); return filteredVariants; } private List<Variant> filterByLanguage(List<AcceptLanguage> acceptLanguages, List<Variant> variants) { List<Variant> filteredVariants = new ArrayList<>(); acceptLanguages.forEach(acceptLanguage -> variants.forEach( variant -> { if (variant.getLanguage() != null && acceptLanguage.isCompatible(new Language(variant.getLanguage()))) { filteredVariants.add(variant); } })); filteredVariants.addAll(variants.stream().filter(variant -> variant.getLanguage() == null).collect(toList())); return filteredVariants; } private List<Variant> filterByCharset(List<AcceptToken> acceptCharsets, List<Variant> variants) { List<Variant> filteredVariants = new ArrayList<>(); acceptCharsets.forEach(acceptCharset -> variants.forEach( variant -> { if (acceptCharset.isCompatible(getCharset(variant.getMediaType()))) { filteredVariants.add(variant); } })); filteredVariants.addAll(variants.stream().filter(variant -> getCharset(variant.getMediaType()) == null).collect(toList())); return filteredVariants; } private String getCharset(MediaType mediaType) { if (mediaType == null) { return null; } return mediaType.getParameters().get("charset"); } private List<Variant> filterByEncoding(List<AcceptToken> acceptEncodings, List<Variant> variants) { List<Variant> filteredVariants = new ArrayList<>(); acceptEncodings.forEach(acceptEncoding -> variants.forEach( variant -> { if (acceptEncoding.isCompatible(variant.getEncoding())) { filteredVariants.add(variant); } })); filteredVariants.addAll(variants.stream().filter(variant -> variant.getEncoding() == null).collect(toList())); return filteredVariants; } }