001: // HttpAccept.java
002: // $Id: HttpAccept.java,v 1.9 2000/08/16 21:37:58 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.www.http;
007:
008: import java.util.Vector;
009:
010: import org.w3c.www.mime.MimeType;
011:
012: public class HttpAccept extends BasicValue {
013: /**
014: * The list of accept parameters name.
015: */
016: protected String aparams[] = null;
017: /**
018: * The list of accept parameters value.
019: */
020: protected String avalues[] = null;
021: /**
022: * The accepted MIME type.
023: */
024: protected MimeType type = null;
025: /**
026: * The list we belong to, if any.
027: */
028: HttpAcceptList list = null;
029: /**
030: * the quality
031: */
032: protected double quality = -1;
033:
034: /**
035: * parse.
036: * @exception HttpParserException if parsing failed.
037: */
038: protected void parse() throws HttpParserException {
039: ParseState ps = new ParseState(roff, rlen);
040: // We need to do our own MIME type parsing, to avoid ambiguities !
041: // Get the type:
042: ps.separator = (byte) '/';
043: ps.spaceIsSep = false;
044: if (HttpParser.nextItem(raw, ps) < 0)
045: error("Invalid Accept: has no type.");
046: String type = new String(raw, 0, ps.start, ps.end - ps.start);
047: // Get the subtype:
048: ps.prepare();
049: ps.separator = (byte) ';';
050: if (HttpParser.nextItem(raw, ps) < 0)
051: error("Invalid accept: no subtype");
052: String subtype = new String(raw, 0, ps.start, ps.end - ps.start);
053: // Get the parameters:
054: ParseState it = new ParseState();
055: it.separator = (byte) '=';
056: it.spaceIsSep = false;
057: ps.prepare();
058: Vector vparams = new Vector(4);
059: Vector vvalues = new Vector(4);
060: boolean accept = false;
061: while (HttpParser.nextItem(raw, ps) >= 0) {
062: it.ioff = ps.start;
063: it.bufend = ps.end;
064: if (HttpParser.nextItem(raw, it) < 0)
065: error("Invalid parameter: no param name.");
066: // The Hack !
067: String param = new String(raw, 0, it.start, it.end
068: - it.start);
069: if (param.equalsIgnoreCase("q")) {
070: // Switching to accept-params
071: accept = true;
072: break;
073: }
074: vparams.addElement(new String(raw, 0, it.start, it.end
075: - it.start));
076: it.prepare();
077: if (HttpParser.nextItem(raw, it) < 0)
078: error("Invalid parameter: no value.");
079: vvalues.addElement(new String(raw, 0, it.start, it.end
080: - it.start));
081: ps.prepare();
082: }
083: if (vparams.size() > 0) {
084: String pparams[] = new String[vparams.size()];
085: String pvalues[] = new String[pparams.length];
086: vparams.copyInto(pparams);
087: vvalues.copyInto(pvalues);
088: this .type = new MimeType(type, subtype, pparams, pvalues);
089: } else {
090: this .type = new MimeType(type, subtype);
091: }
092: // Parse remaining accept parameters:
093: if (accept) {
094: vparams.setSize(0);
095: vvalues.setSize(0);
096: // Hack to finish with the q parameter
097: it.prepare();
098: if (HttpParser.nextItem(raw, it) < 0)
099: error("Invalid accept parameter: no value.");
100: vparams.addElement("q");
101: vvalues.addElement(new String(raw, 0, it.start, it.end
102: - it.start));
103: it.prepare();
104: while (HttpParser.nextItem(raw, ps) >= 0) {
105: it.ioff = ps.start;
106: it.bufend = ps.end;
107: if (HttpParser.nextItem(raw, it) < 0)
108: error("Invalid accept parameter: no name.");
109: vparams.addElement(new String(raw, 0, it.start, it.end
110: - it.start));
111: it.prepare();
112: if (HttpParser.nextItem(raw, it) < 0)
113: error("Invalid accept parameter: no value.");
114: vvalues.addElement(new String(raw, 0, it.start, it.end
115: - it.start));
116: ps.prepare();
117: }
118: this .aparams = new String[vparams.size()];
119: this .avalues = new String[aparams.length];
120: vparams.copyInto(aparams);
121: vvalues.copyInto(avalues);
122: }
123: }
124:
125: protected void updateByteValue() {
126: HttpBuffer buf = new HttpBuffer();
127: buf.append(type.toString());
128: if (aparams != null) {
129: for (int i = 0; i < aparams.length; i++) {
130: if (i > 0)
131: buf.append(';');
132: buf.append(aparams[i], (byte) '=', avalues[i]);
133: }
134: }
135: raw = buf.getByteCopy();
136: roff = 0;
137: rlen = raw.length;
138: }
139:
140: protected void invalideByteValue() {
141: super .invalidateByteValue();
142: if (list != null)
143: list.invalidateByteValue();
144: }
145:
146: public Object getValue() {
147: validate();
148: return this ;
149: }
150:
151: /**
152: * Lookup for the given parameter binding.
153: * @return The slot number for this parameter, or <strong>-1</strong>
154: * if undefined.
155: */
156:
157: protected int lookup(String name) {
158: if (aparams == null)
159: return -1;
160: for (int i = 0; i < aparams.length; i++) {
161: if (name.equalsIgnoreCase(aparams[i]))
162: return i;
163: }
164: return -1;
165: }
166:
167: /**
168: * Get the String value for a parameter.
169: * @return The String value for the accept parameter, or
170: * <strong>null</strong> if undefined.
171: */
172:
173: public String getAcceptParameter(String name) {
174: validate();
175: int slot = lookup(name);
176: return (slot == -1) ? null : avalues[slot];
177: }
178:
179: /**
180: * Set the value of an accept parameter.
181: * @param name The name of the accept parameter to set.
182: * @param value The value of the accept parameter to set.
183: */
184:
185: public void setAcceptParameter(String name, String value) {
186: validate();
187: int slot = lookup(name);
188: if (slot == -1) {
189: // Look for a free slot:
190: for (int i = 0; i < aparams.length; i++) {
191: if (aparams[i] == null) {
192: slot = i;
193: break;
194: }
195: }
196: // Do we need to resize ?
197: if (slot == -1) {
198: slot = aparams.length;
199: String nap[] = new String[slot << 1];
200: String nav[] = new String[nap.length];
201: System.arraycopy(aparams, 0, nap, 0, slot);
202: System.arraycopy(avalues, 0, nav, 0, slot);
203: aparams = nap;
204: avalues = nav;
205: }
206: }
207: // Set the slot value:
208: invalidateByteValue();
209: aparams[slot] = name;
210: avalues[slot] = value;
211: }
212:
213: /**
214: * Get this object accepted MIME type.
215: * @return The accepted MIME type.
216: */
217:
218: public MimeType getMimeType() {
219: validate();
220: return type;
221: }
222:
223: /**
224: * Set the accepted MIME type.
225: * @param type The accepted MIME type.
226: */
227:
228: public void setMimeType(MimeType type) {
229: invalidateByteValue();
230: this .type = type;
231: }
232:
233: /**
234: * Get the quality of this accept clause.
235: * @return A double value, encoding the quality, or <strong>1.0</strong>
236: * if undefined.
237: */
238:
239: public double getQuality() {
240: String value = getAcceptParameter("q");
241: if (value == null) {
242: if (quality != -1) {
243: return quality;
244: }
245: String strtype = type.getType();
246: String strsubtype = type.getSubtype();
247: if (strtype.equals("*"))
248: return strsubtype.equals("*") ? 0.1 : 0.5;
249: return strsubtype.equals("*") ? 0.5 : 1.0;
250: }
251: try {
252: return Double.valueOf(value).doubleValue();
253: } catch (Exception ex) {
254: String msg = "invalid quality value: " + value;
255: throw new HttpInvalidValueException(msg);
256: }
257: }
258:
259: HttpAccept(HttpAcceptList list, byte raw[], int roff, int rlen) {
260: this .list = list;
261: this .raw = raw;
262: this .roff = roff;
263: this .rlen = rlen;
264: this .isValid = false;
265: }
266:
267: HttpAccept(boolean isValid, MimeType type, double quality) {
268: this .isValid = isValid;
269: setMimeType(type);
270: this .quality = quality;
271: }
272:
273: public HttpAccept() {
274: this .isValid = false;
275: }
276:
277: }
|