// Turn a comma separated string of accepted mime types into a Map // based on the list of mime types that can be provided private static Map normaliseWantedMap(final String accept, final List canProvide) { Map map = new LinkedHashMap(); String[] array = accept.split(","); for (int i = 0; i < array.length; i++) { String mimeType = array[i].trim(); String major = getMediaType(mimeType); String minor = getSubType(mimeType); double qos = getMimeQuality(mimeType); if (StringUtil.contains(major, "*")) { // All canProvide types are acceptable with the qos defined OR // 0.01 if not defined Iterator it = canProvide.iterator(); while (it.hasNext()) { String mt = (String) it.next(); List list = (List) map.get(getMediaType(mt)); if (list == null) { list = new ArrayList(); } list.add(mt + ";q=" + qos); map.put(getMediaType(mt), list); } } else if (StringUtil.contains(minor, "*")) { Iterator it = canProvide.iterator(); while (it.hasNext()) { String mt = (String) it.next(); if (getMediaType(mt).equals(major)) { List list = (List) map.get(major); if (list == null) { list = new ArrayList(); } list.add(major + "/" + getSubType(mt) + ";q=" + qos); map.put(major, list); } } } else { if (canProvide.contains(major + "/" + minor)) { List list = (List) map.get(major); if (list == null) { list = new ArrayList(); } list.add(major + "/" + minor + ";q=" + qos); map.put(major, list); } } } return map; }
/** * Get a Collection of possible MimeType(s) that this byte array could represent according to the * registered MimeDetector(s). If no MimeType(s) are detected then the returned Collection will * contain only the passed in unknownMimeType * * @param data * @param unknownMimeType used if the registered MimeDetector(s) fail to match any MimeType(s) * @return all matching MimeType(s) * @throws MimeException */ public final Collection getMimeTypes(final byte[] data, final MimeType unknownMimeType) throws MimeException { Collection mimeTypes = new MimeTypeHashSet(); if (data == null) { log.error("byte array cannot be null."); } else { if (log.isDebugEnabled()) { try { log.trace("Getting MIME types for byte array [" + StringUtil.getHexString(data) + "]."); } catch (UnsupportedEncodingException e) { throw new MimeException(e); } } mimeTypes.addAll(mimeDetectorRegistry.getMimeTypes(data)); // We don't want the unknownMimeType added to the collection by MimeDetector(s) mimeTypes.remove(unknownMimeType); } // If the collection is empty we want to add the unknownMimetype if (mimeTypes.isEmpty()) { mimeTypes.add(unknownMimeType); } if (log.isDebugEnabled()) { log.debug("Retrieved MIME types [" + mimeTypes.toString() + "]"); } return mimeTypes; }
/** * Utility method to get the quality part of a mime type. If it does not exist then it is always * set to q=1.0 unless it's a wild card. For the major component wild card the value is set to * 0.01 For the minor component wild card the value is set to 0.02 * * <p>Thanks to the Apache organisation for these settings. * * @param mimeType a valid mime type string with or without a valid q parameter * @return the quality value of the mime type either calculated from the rules above or the actual * value defined. * @throws MimeException this is thrown if the mime type pattern is invalid. */ public static double getMimeQuality(final String mimeType) throws MimeException { if (mimeType == null) { throw new MimeException("Invalid MimeType [" + mimeType + "]."); } String[] parts = mimeSplitter.split(mimeType); if (parts.length < 2) { throw new MimeException("Invalid MimeType [" + mimeType + "]."); } if (parts.length > 2) { for (int i = 2; i < parts.length; i++) { if (parts[i].trim().startsWith("q=")) { // Get the number part try { // Get the quality factor double d = Double.parseDouble(parts[i].split("=")[1].trim()); return d > 1.0 ? 1.0 : d; } catch (NumberFormatException e) { throw new MimeException( "Invalid MIME quality indicator [" + parts[i].trim() + "]. Must be a valid double between 0 and 1"); } catch (Exception e) { throw new MimeException("Error parsing MIME quality indicator.", e); } } } } // No quality indicator so always assume its 1 unless a wild card is used if (StringUtil.contains(parts[0], "*")) { return 0.01; } else if (StringUtil.contains(parts[1], "*")) { return 0.02; } else { // Assume q value of 1 return 1.0; } }