/**
  * Returns {@code true} if the given media type includes any of the {@linkplain
  * #setSupportedMediaTypes(List) supported media types}.
  *
  * @param mediaType the media type to write, can be {@code null} if not specified. Typically the
  *     value of an {@code Accept} header.
  * @return {@code true} if the supported media types are compatible with the media type, or if the
  *     media type is {@code null}
  */
 protected boolean canWrite(MediaType mediaType) {
   if (mediaType == null || MediaType.ALL.equals(mediaType)) {
     return true;
   }
   for (MediaType supportedMediaType : getSupportedMediaTypes()) {
     if (supportedMediaType.isCompatibleWith(mediaType)) {
       return true;
     }
   }
   return false;
 }
 public boolean canWrite(Class<?> clazz, MediaType mediaType) {
   if (!Map.class.isAssignableFrom(clazz)) {
     return false;
   }
   if (mediaType == null || MediaType.ALL.equals(mediaType)) {
     return true;
   }
   for (MediaType supportedMediaType : getSupportedMediaTypes()) {
     if (supportedMediaType.isCompatibleWith(mediaType)) {
       return true;
     }
   }
   return false;
 }
  @Test
  public void isCompatible() throws Exception {
    MediaType textPlain = MediaType.TEXT_PLAIN;
    assertTrue("Equal types is not compatible", textPlain.isCompatibleWith(textPlain));
    MediaType allText = new MediaType("text");

    assertTrue("All subtypes is not compatible", allText.isCompatibleWith(textPlain));
    assertTrue("All subtypes is not compatible", textPlain.isCompatibleWith(allText));

    assertTrue("All types is not compatible", MediaType.ALL.isCompatibleWith(textPlain));
    assertTrue("All types is not compatible", textPlain.isCompatibleWith(MediaType.ALL));

    assertTrue("All types is not compatible", MediaType.ALL.isCompatibleWith(textPlain));
    assertTrue("All types is compatible", textPlain.isCompatibleWith(MediaType.ALL));

    MediaType applicationSoapXml = new MediaType("application", "soap+xml");
    MediaType applicationWildcardXml = new MediaType("application", "*+xml");

    assertTrue(applicationSoapXml.isCompatibleWith(applicationSoapXml));
    assertTrue(applicationWildcardXml.isCompatibleWith(applicationWildcardXml));

    assertTrue(applicationWildcardXml.isCompatibleWith(applicationSoapXml));
    assertTrue(applicationSoapXml.isCompatibleWith(applicationWildcardXml));
  }
 /**
  * Determines the list of {@link MediaType} for the given {@link HttpServletRequest}.
  *
  * <p>The default implementation invokes {@link #getMediaTypeFromFilename(String)} if {@linkplain
  * #setFavorPathExtension favorPathExtension} property is <code>true</code>. If the property is
  * <code>false</code>, or when a media type cannot be determined from the request path, this
  * method will inspect the {@code Accept} header of the request.
  *
  * <p>This method can be overridden to provide a different algorithm.
  *
  * @param request the current servlet request
  * @return the list of media types requested, if any
  */
 protected List<MediaType> getMediaTypes(HttpServletRequest request) {
   if (this.favorPathExtension) {
     String requestUri = urlPathHelper.getLookupPathForRequest(request);
     String filename = WebUtils.extractFullFilenameFromUrlPath(requestUri);
     MediaType mediaType = getMediaTypeFromFilename(filename);
     if (mediaType != null) {
       if (logger.isDebugEnabled()) {
         logger.debug(
             "Requested media type is '" + mediaType + "' (based on filename '" + filename + "')");
       }
       return Collections.singletonList(mediaType);
     }
   }
   if (this.favorParameter) {
     if (request.getParameter(this.parameterName) != null) {
       String parameterValue = request.getParameter(this.parameterName);
       MediaType mediaType = getMediaTypeFromParameter(parameterValue);
       if (mediaType != null) {
         if (logger.isDebugEnabled()) {
           logger.debug(
               "Requested media type is '"
                   + mediaType
                   + "' (based on parameter '"
                   + this.parameterName
                   + "'='"
                   + parameterValue
                   + "')");
         }
         return Collections.singletonList(mediaType);
       }
     }
   }
   if (!this.ignoreAcceptHeader) {
     String acceptHeader = request.getHeader(ACCEPT_HEADER);
     if (StringUtils.hasText(acceptHeader)) {
       try {
         List<MediaType> acceptableMediaTypes = MediaType.parseMediaTypes(acceptHeader);
         List<MediaType> producibleMediaTypes = getProducibleMediaTypes(request);
         Set<MediaType> compatibleMediaTypes = new LinkedHashSet<MediaType>();
         for (MediaType acceptable : acceptableMediaTypes) {
           for (MediaType producible : producibleMediaTypes) {
             if (acceptable.isCompatibleWith(producible)) {
               compatibleMediaTypes.add(getMostSpecificMediaType(acceptable, producible));
             }
           }
         }
         List<MediaType> mediaTypes = new ArrayList<MediaType>(compatibleMediaTypes);
         MediaType.sortByQualityValue(mediaTypes);
         if (logger.isDebugEnabled()) {
           logger.debug(
               "Requested media types are "
                   + mediaTypes
                   + " based on Accept header types "
                   + "and producible media types "
                   + producibleMediaTypes
                   + ")");
         }
         return mediaTypes;
       } catch (IllegalArgumentException ex) {
         if (logger.isDebugEnabled()) {
           logger.debug(
               "Could not parse accept header [" + acceptHeader + "]: " + ex.getMessage());
         }
         return null;
       }
     }
   }
   if (this.defaultContentType != null) {
     if (logger.isDebugEnabled()) {
       logger.debug(
           "Requested media types is "
               + this.defaultContentType
               + " (based on defaultContentType property)");
     }
     return Collections.singletonList(this.defaultContentType);
   } else {
     return Collections.emptyList();
   }
 }