package org.openstack.atlas.api.filters.helpers;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class AcceptType implements Comparable<AcceptType> {
private MediaType mediaType;
private double q = 1.0;
private List<String> acceptExtensions = new ArrayList<String>();
private static final Pattern qRe = Pattern.compile("^\\s*[qQ]\\s*=\\s*([0-9]+\\.?[0-9]*)\\s*$");
public AcceptType() {
}
public MediaType getMediaType() {
return mediaType;
}
public static AcceptType newInstance(String strIn) {
Double q;
AcceptType out = null;
MediaType mtIn;
MediaType mtOut = new MediaType();
List<String> acExtList = new ArrayList<String>();
String curParameter;
int i;
if (strIn == null) {
return null;
}
mtIn = MediaType.newInstance(strIn);
if (mtIn == null) {
return out;
}
out = new AcceptType();
out.setMediaType(mtOut);
out.setAcceptExtensions(acExtList);
mtOut.setType(mtIn.getType());
mtOut.setSubtype(mtIn.getSubtype());
i = 0;
for (i = 0; i < mtIn.getParameters().size(); i++) {
curParameter = mtIn.getParameters().get(i);
q = AcceptType.getQfromString(curParameter);
if (q != null) {
out.setQ(q);
i++;
break;
}
mtOut.getParameters().add(curParameter);
}
for (; i < mtIn.getParameters().size(); i++) {
acExtList.add(mtIn.getParameters().get(i));
}
return out;
}
public String toString() {
StringBuilder sb = new StringBuilder();
try {
sb.append(String.format("%s/%s", this.getMediaType().getType(), this.getMediaType().getSubtype()));
for (String parameter : this.getMediaType().getParameters()) {
sb.append(String.format(";%s", parameter));
}
sb.append(String.format(";q=%.2f", this.getQ()));
for (String ext : this.getAcceptExtensions()) {
sb.append(String.format(";%s", ext));
}
} catch (NullPointerException ex) {
return null;
}
return sb.toString();
}
public static boolean isAcceptableMedia(AcceptType requested, AcceptType offerd) {
String rType = requested.getMediaType().getType().toLowerCase();
String oType = offerd.getMediaType().getType().toLowerCase();
String rSub = requested.getMediaType().getSubtype();
String oSub = offerd.getMediaType().getSubtype();
if (rType.equals("*")) {
return true;
}
if (rType.equals(oType) && rSub.equals("*")) {
return true;
}
if (rType.equals(oType) && rSub.equals(oSub)) {
return true;
}
return false;
}
public static boolean mediaMatch(AcceptType t, AcceptType o) {
try {
String ttype = t.getMediaType().getType();
String otype = o.getMediaType().getType();
String tsub = t.getMediaType().getSubtype();
String osub = o.getMediaType().getSubtype();
List<String> tparams = t.getMediaType().getParameters();
List<String> oparams = t.getMediaType().getParameters();
int i;
if (!ttype.equals(otype)) {
return false;
}
if (!tsub.equals(osub)) {
return false;
}
if (tparams.size() != oparams.size()) {
return false;
}
for (i = 0; i < oparams.size(); i++) {
if (!tparams.get(i).equals(oparams.get(i))) {
return false;
}
}
return true;
} catch (NullPointerException ex) {
return false;
}
}
@Override
public int compareTo(AcceptType o) {
// Sorts the AcceptType according to according to HttpClient preferences
// According to Section 14.1 of the Http/1.1 protocol
double oq = o.getQ();
double mq = this.getQ();
String otype = o.getMediaType().getSubtype();
String osubtype = o.getMediaType().getSubtype();
String mtype = this.getMediaType().getType();
String msubtype = this.getMediaType().getSubtype();
int mscore = 0;
int oscore = 0;
// If the q values are different choose the highest one
if (mq > oq) {
return -1;
}
if (mq < oq) {
return 1;
}
// Try to tie break off * protocols since * should have less presedence
// type is worth 2 points subtype is just worth 1
mscore = ((msubtype.equals("*")) ? 0 : 1) + ((mtype.equals("*")) ? 0 : 2);
oscore = ((osubtype.equals("*")) ? 0 : 1) + ((otype.equals("*")) ? 0 : 2);
if (mscore != oscore) {
return oscore - mscore;
}
//If you still have a tie the go by the number of parameters since they are
//more specific as suggested by the HTTP/1.1 section 14.1
oscore = o.getMediaType().getParameters().size();
mscore = this.getMediaType().getParameters().size();
return oscore - mscore;
}
public void setMediaType(MediaType mediaType) {
this.mediaType = mediaType;
}
public double getQ() {
return q;
}
public void setQ(double q) {
this.q = q;
}
public List<String> getAcceptExtensions() {
return acceptExtensions;
}
public void setAcceptExtensions(List<String> acceptExtensions) {
this.acceptExtensions = acceptExtensions;
}
public static Double getQfromString(String strIn) {
Matcher matcher = qRe.matcher(strIn);
if (!matcher.find()) {
return null;
}
return Double.parseDouble(matcher.group(1));
}
}