package org.jboss.resteasy.core.request; import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages; import org.jboss.resteasy.spi.BadRequestException; /** * @author Pascal S. de Kloe * @see "RFC2616 3.9 Quality Values" */ public final class QualityValue extends Number implements Comparable<QualityValue> { public static final QualityValue NOT_ACCEPTABLE = new QualityValue(0); public static final QualityValue LOWEST = new QualityValue(1); public static final QualityValue HIGHEST = new QualityValue(1000); public static final QualityValue DEFAULT = HIGHEST; private static final long serialVersionUID = 1L; private static final String MALFORMED_VALUE_MESSAGE = Messages.MESSAGES.malformedQualityValue(); private final int WEIGHT; private QualityValue(int weight) { assert weight >= 0; assert weight <= 1000; WEIGHT = weight; } /** * @param qvalue the quality value or {@code null} if undefined. */ public static QualityValue valueOf(String qvalue) { if (qvalue == null) return DEFAULT; return new QualityValue(parseAsInteger(qvalue)); } public boolean isPrefered() { return WEIGHT == HIGHEST.WEIGHT; } public boolean isAcceptable() { return WEIGHT != NOT_ACCEPTABLE.WEIGHT; } public int compareTo(QualityValue o) { return WEIGHT - o.WEIGHT; } @Override public boolean equals(Object o) { if (o == null || o.getClass() != QualityValue.class) return false; QualityValue other = (QualityValue) o; return WEIGHT == other.WEIGHT; } @Override public int hashCode() { return WEIGHT; } @Override public double doubleValue() { return (double) WEIGHT / 1000d; } @Override public float floatValue() { return (float) WEIGHT / 1000f; } @Override public int intValue() { return WEIGHT; } @Override public long longValue() { return WEIGHT; } private static int parseAsInteger(String value) { int length = value.length(); if (length == 0 || length > 5) throw new BadRequestException(MALFORMED_VALUE_MESSAGE); if (length > 1 && value.charAt(1) != '.') throw new BadRequestException(MALFORMED_VALUE_MESSAGE); int firstCharacter = value.codePointAt(0); if (firstCharacter == '1') { for (int i = 2; i < length; ++i) if (value.charAt(i) != '0') throw new BadRequestException(MALFORMED_VALUE_MESSAGE); return 1000; } else if (firstCharacter == '0') { int weight = 0; for (int i = 2; i < 5; ++i) { weight *= 10; if (i < length) { int digit = value.codePointAt(i) - '0'; if (digit < 0 || digit > 9) throw new BadRequestException(MALFORMED_VALUE_MESSAGE); weight += digit; } } return weight; } else throw new BadRequestException(MALFORMED_VALUE_MESSAGE); } }