// Copyright (c) 2002-2005 Canoo Engineering AG, Switzerland. All Rights Reserved. package com.canoo.webtest.extension; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; /** * @author Denis N. Antonioli */ public class MimeType { public static final MimeType ALL_MEDIA; static { ALL_MEDIA = new MimeType(); } private final List<MediaRange> fMediaRanges = new ArrayList<MediaRange>(); private MimeType() { fMediaRanges.add(MediaRange.ALL_MEDIA_RANGES); } public MimeType(final String mimeType) { final String mts[] = mimeType.split("\\s*;\\s*"); for (int i = 0; i < mts.length; i++) { fMediaRanges.add(MediaRange.create(mts[i])); } if (!fMediaRanges.isEmpty()) { Collections.sort(fMediaRanges); if (fMediaRanges.get(0) instanceof AllMediaRanges) { fMediaRanges.clear(); fMediaRanges.add(MediaRange.ALL_MEDIA_RANGES); } else { final List<MediaRange> original = new ArrayList<MediaRange>(fMediaRanges); fMediaRanges.clear(); final Iterator it = original.iterator(); MediaRange lastMR = (MediaRange) it.next(); fMediaRanges.add(lastMR); while (it.hasNext()) { final MediaRange mediaRange = (MediaRange) it.next(); if (lastMR instanceof AllSubtypesMediaRanges && lastMR.getType().equals(mediaRange.getType())) { continue; } fMediaRanges.add(mediaRange); lastMR = mediaRange; } } } } public boolean match(final String contentType) { for (Iterator it = fMediaRanges.iterator(); it.hasNext();) { if (((MediaRange) it.next()).match(contentType)) { return true; } } return false; } public String toString() { StringBuffer sb = new StringBuffer(); for (Iterator it = fMediaRanges.iterator(); it.hasNext();) { sb.append(it.next().toString()).append(";"); } sb.setLength(sb.length() - 1); return sb.toString(); } protected static class MediaRange implements Comparable<MediaRange> { private final String fType; private final String fSubtype; static final AllMediaRanges ALL_MEDIA_RANGES; static { ALL_MEDIA_RANGES = new AllMediaRanges(); } public static MediaRange create(final String mymetype) { if ("*/*".equals(mymetype)) { return ALL_MEDIA_RANGES; } if (mymetype.startsWith("*/")) { throw new IllegalArgumentException("'" + mymetype + "' is not a valid syntax."); } if (mymetype.endsWith("/*")) { return new AllSubtypesMediaRanges(mymetype); } return new MediaRange(mymetype); } protected MediaRange(final String mymetype) { int idx = mymetype.indexOf("/"); if (idx == -1) { throw new IllegalArgumentException("'" + mymetype + "' is not a valid syntax."); } fType = mymetype.substring(0, idx + 1); fSubtype = mymetype.substring(idx); } public boolean match(final String contentType) { return matchType(contentType) && matchSubtype(contentType); } boolean matchSubtype(final String contentType) { return contentType.endsWith(fSubtype); } boolean matchType(final String contentType) { return contentType.startsWith(fType); } public String getType() { return fType; } public String getSubtype() { return fSubtype; } public String toString() { return fType + fSubtype.substring(1); } public int compareTo(final MediaRange other) { if (other instanceof AllMediaRanges) { return 1; } int typeCmp = getType().compareTo(other.getType()); if (typeCmp != 0) { return typeCmp; } if (other instanceof AllSubtypesMediaRanges) { return 1; } return getSubtype().compareTo(other.getSubtype()); } } static class AllMediaRanges extends MediaRange { AllMediaRanges() { super("*/*"); } public boolean match(final String contentType) { return true; } public int compareTo(final MediaRange other) { if (other instanceof AllMediaRanges) { return 0; } return -1; } } static class AllSubtypesMediaRanges extends MediaRange { AllSubtypesMediaRanges(final String mimetype) { super(mimetype); } public boolean match(final String contentType) { return matchType(contentType); } public int compareTo(final MediaRange other) { if (other instanceof AllMediaRanges) { return 1; } int typeCmp = getType().compareTo(other.getType()); if (typeCmp != 0) { return typeCmp; } if (other instanceof AllSubtypesMediaRanges) { return 0; } return -1; } } }