001: // HttpCacheControl.java
002: // $Id: HttpCacheControl.java,v 1.22 2003/02/24 14:25:19 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.Enumeration;
009: import java.util.Vector;
010:
011: /**
012: * The parsed cache-control directive of HTTP/1.1
013: * This object gives access to the parsed value of the cache-control
014: * directive of HTTP/1.1, as defined in section 14.9 of the specification.
015: */
016:
017: public class HttpCacheControl extends BasicValue {
018: private static final String EMPTY_LIST[] = {};
019:
020: private String nocache[] = null;
021: private boolean nostore = false;
022: private int maxage = -1;
023: private int maxstale = -1;
024: private int minfresh = -1;
025: private boolean onlyifcached = false;
026: private boolean pub = false;
027: private String priv[] = null;
028: private boolean notransform = false;
029: private boolean mustrevalidate = false;
030: private boolean proxyrevalidate = false;
031: private int s_maxage = -1;
032: private Vector extensions = null;
033:
034: private static final int NOCACHE = (1 << 0);
035: private static final int NOSTORE = (1 << 1);
036: private static final int MAXAGE = (1 << 2);
037: private static final int MINVERS = (1 << 3);
038: private static final int ONLYIFCACHED = (1 << 4);
039: private static final int PUB = (1 << 5);
040: private static final int PRIV = (1 << 6);
041: private static final int NOTRANSFORM = (1 << 7);
042: private static final int MUSTREVALIDATE = (1 << 8);
043: private static final int PROXYREVALIDATE = (1 << 9);
044: private static final int MAXSTALE = (1 << 10);
045: private static final int MINFRESH = (1 << 11);
046: private static final int S_MAXAGE = (1 << 12);
047:
048: private int defined = 0;
049:
050: /**
051: * Check if the given field has been explictly set.
052: * @param id The field identifier.
053: * @return A boolean.
054: */
055:
056: private final boolean checkDirective(int id) {
057: return (defined & id) != 0;
058: }
059:
060: /**
061: * Mark the given field as being set.
062: * @param id The field identifier.
063: */
064:
065: private final void setDirective(int id) {
066: defined |= id;
067: }
068:
069: /**
070: * Mark the given field as being unset.
071: * @param id The field identifier.
072: */
073:
074: private final void unsetDirective(int id) {
075: defined &= (~id);
076: }
077:
078: /**
079: * Recompute the byte value for this header.
080: */
081:
082: protected void updateByteValue() {
083: // Dump the value, using my own version of the StringBuffer:
084: HttpBuffer buf = new HttpBuffer();
085: boolean cnt = false;
086: if (checkDirective(NOCACHE)) {
087: if (nocache != null)
088: buf.appendQuoted("no-cache", (byte) '=', nocache);
089: else
090: buf.append("no-cache");
091: cnt = true;
092: }
093: if (checkDirective(NOSTORE) && nostore) {
094: buf.append("no-store");
095: cnt = true;
096: }
097: if (checkDirective(MAXAGE) && (maxage >= 0)) {
098: if (cnt)
099: buf.append(',');
100: buf.append("max-age", (byte) '=', maxage);
101: cnt = true;
102: }
103: if (checkDirective(ONLYIFCACHED) && onlyifcached) {
104: if (cnt)
105: buf.append(',');
106: buf.append("only-if-cached");
107: cnt = true;
108: }
109: if (checkDirective(PUB) && pub) {
110: if (cnt)
111: buf.append(',');
112: buf.append("public");
113: cnt = true;
114: }
115: if (checkDirective(PRIV) && (priv != null)) {
116: if (cnt)
117: buf.append(',');
118: buf.appendQuoted("private", (byte) '=', priv);
119: cnt = true;
120: }
121: if (checkDirective(NOTRANSFORM) && notransform) {
122: if (cnt)
123: buf.append(',');
124: buf.append("no-transform");
125: cnt = true;
126: }
127: if (checkDirective(MUSTREVALIDATE) && mustrevalidate) {
128: if (cnt)
129: buf.append(',');
130: buf.append("must-revalidate");
131: cnt = true;
132: }
133: if (checkDirective(PROXYREVALIDATE) && proxyrevalidate) {
134: if (cnt)
135: buf.append(',');
136: buf.append("proxy-revalidate");
137: cnt = true;
138: }
139: if (checkDirective(MAXSTALE) && (maxstale >= 0)) {
140: if (cnt)
141: buf.append(',');
142: buf.append("max-stale", (byte) '=', maxstale);
143: cnt = true;
144: }
145: if (checkDirective(MINFRESH) && (minfresh >= 0)) {
146: if (cnt)
147: buf.append(',');
148: buf.append("min-fresh", (byte) '=', minfresh);
149: cnt = true;
150: }
151: if (checkDirective(S_MAXAGE) && (s_maxage >= 0)) {
152: if (cnt)
153: buf.append(',');
154: buf.append("s_maxage", (byte) '=', s_maxage);
155: cnt = true;
156: }
157: if (extensions != null) {
158: Enumeration e = extensions.elements();
159: while (e.hasMoreElements()) {
160: if (cnt) {
161: buf.append(',');
162: cnt = true;
163: }
164: buf.append((String) e.nextElement());
165: }
166: }
167: // Keep track of the string, for potential reuse:
168: raw = buf.getByteCopy();
169: roff = 0;
170: rlen = raw.length;
171: }
172:
173: // Efficient regular expression is what I would do in C
174:
175: private static byte bnocache[] = { (byte) 'n', (byte) 'o',
176: (byte) '-', (byte) 'c', (byte) 'a', (byte) 'c', (byte) 'h',
177: (byte) 'e' };
178: private static byte bnostore[] = { (byte) 'n', (byte) 'o',
179: (byte) '-', (byte) 's', (byte) 't', (byte) 'o', (byte) 'r',
180: (byte) 'e' };
181: private static final byte bmaxage[] = { (byte) 'm', (byte) 'a',
182: (byte) 'x', (byte) '-', (byte) 'a', (byte) 'g', (byte) 'e' };
183: private static final byte bs_maxage[] = { (byte) 's', (byte) '-',
184: (byte) 'm', (byte) 'a', (byte) 'x', (byte) 'a', (byte) 'g',
185: (byte) 'e' };
186: private static final byte bmaxstale[] = { (byte) 'm', (byte) 'a',
187: (byte) 'x', (byte) '-', (byte) 's', (byte) 't', (byte) 'a',
188: (byte) 'l', (byte) 'e' };
189: private static final byte bminfresh[] = { (byte) 'm', (byte) 'i',
190: (byte) 'n', (byte) '-', (byte) 'f', (byte) 'r', (byte) 'e',
191: (byte) 's', (byte) 'h' };
192: private static final byte bonlyifcached[] = { (byte) 'o',
193: (byte) 'n', (byte) 'l', (byte) 'y', (byte) '-', (byte) 'i',
194: (byte) 'f', (byte) '-', (byte) 'c', (byte) 'a', (byte) 'c',
195: (byte) 'h', (byte) 'e', (byte) 'd' };
196: private static final byte bpublic[] = { (byte) 'p', (byte) 'u',
197: (byte) 'b', (byte) 'l', (byte) 'i', (byte) 'c', };
198: private static final byte bprivate[] = { (byte) 'p', (byte) 'r',
199: (byte) 'i', (byte) 'v', (byte) 'a', (byte) 't', (byte) 'e' };
200: private static final byte bnotransform[] = { (byte) 'n',
201: (byte) 'o', (byte) '-', (byte) 't', (byte) 'r', (byte) 'a',
202: (byte) 'n', (byte) 's', (byte) 'f', (byte) 'o', (byte) 'r',
203: (byte) 'm' };
204: private static final byte bmustrevalidate[] = { (byte) 'm',
205: (byte) 'u', (byte) 's', (byte) 't', (byte) '-', (byte) 'r',
206: (byte) 'e', (byte) 'v', (byte) 'a', (byte) 'l', (byte) 'i',
207: (byte) 'd', (byte) 'a', (byte) 't', (byte) 'e' };
208: private static final byte bproxyrevalidate[] = { (byte) 'p',
209: (byte) 'r', (byte) 'o', (byte) 'x', (byte) 'y', (byte) '-',
210: (byte) 'r', (byte) 'e', (byte) 'v', (byte) 'a', (byte) 'l',
211: (byte) 'i', (byte) 'd', (byte) 'a', (byte) 't', (byte) 'e' };
212:
213: // Parse a valued-directive
214: private final void parseDirective(int ds, int de, ParseState pval)
215: throws HttpParserException {
216: if (HttpParser.compare(raw, ds, de, bmaxage) == 0) {
217: pval.ioff = pval.start;
218: pval.bufend = pval.end;
219: maxage = HttpParser.parseInt(raw, pval);
220: setDirective(MAXAGE);
221: } else if (HttpParser.compare(raw, ds, de, bmaxstale) == 0) {
222: pval.ioff = pval.start;
223: pval.bufend = pval.end;
224: maxstale = HttpParser.parseInt(raw, pval);
225: setDirective(MAXSTALE);
226: } else if (HttpParser.compare(raw, ds, de, bminfresh) == 0) {
227: pval.ioff = pval.start;
228: pval.bufend = pval.end;
229: minfresh = HttpParser.parseInt(raw, pval);
230: setDirective(MINFRESH);
231: } else if (HttpParser.compare(raw, ds, de, bs_maxage) == 0) {
232: pval.ioff = pval.start;
233: pval.bufend = pval.end;
234: s_maxage = HttpParser.parseInt(raw, pval);
235: setDirective(S_MAXAGE);
236: } else if (HttpParser.compare(raw, ds, de, bnocache) == 0) {
237: Vector fields = new Vector(8);
238: ParseState sp = new ParseState();
239: sp.ioff = pval.start;
240: sp.bufend = pval.end;
241: HttpParser.unquote(raw, sp);
242: while (HttpParser.nextItem(raw, sp) >= 0) {
243: fields.addElement(new String(raw, 0, sp.start, sp.end
244: - sp.start));
245: sp.prepare();
246: }
247: if (nocache == null) {
248: nocache = new String[fields.size()];
249: fields.copyInto(nocache);
250: } else {
251: int num = fields.size();
252: String t_nocache[] = new String[nocache.length + num];
253: System.arraycopy(nocache, 0, t_nocache, 0,
254: nocache.length);
255: for (int i = 0; i < num; i++) {
256: t_nocache[nocache.length + i] = (String) fields
257: .elementAt(i);
258: }
259: nocache = t_nocache;
260: }
261: setDirective(NOCACHE);
262: } else if (HttpParser.compare(raw, ds, de, bprivate) == 0) {
263: Vector fields = new Vector(8);
264: ParseState sp = new ParseState();
265: sp.ioff = pval.start;
266: sp.bufend = pval.end;
267: HttpParser.unquote(raw, sp);
268: while (HttpParser.nextItem(raw, sp) >= 0) {
269: fields.addElement(new String(raw, 0, sp.start, sp.end
270: - sp.start));
271: sp.prepare();
272: }
273: if (priv == null) {
274: priv = new String[fields.size()];
275: fields.copyInto(priv);
276: } else {
277: int num = fields.size();
278: String t_priv[] = new String[priv.length + num];
279: System.arraycopy(priv, 0, t_priv, 0, priv.length);
280: for (int i = 0; i < num; i++) {
281: t_priv[priv.length + i] = (String) fields
282: .elementAt(i);
283: }
284: priv = t_priv;
285: }
286: setDirective(PRIV);
287: } else {
288: if (extensions == null) {
289: extensions = new Vector(4);
290: extensions.add(new String(raw, 0, ds, de - ds));
291: }
292: // error("Unknown directive "+new String(raw, 0, ds, de-ds));
293: }
294: }
295:
296: // Parse a boolean directive
297: private final void parseDirective(int ds, int de)
298: throws HttpParserException {
299: if (HttpParser.compare(raw, ds, de, bnocache) == 0) {
300: setDirective(NOCACHE);
301: nocache = EMPTY_LIST;
302: } else if (HttpParser.compare(raw, ds, de, bnostore) == 0) {
303: setDirective(NOSTORE);
304: nostore = true;
305: } else if (HttpParser.compare(raw, ds, de, bonlyifcached) == 0) {
306: setDirective(ONLYIFCACHED);
307: onlyifcached = true;
308: } else if (HttpParser.compare(raw, ds, de, bpublic) == 0) {
309: setDirective(PUB);
310: pub = true;
311: } else if (HttpParser.compare(raw, ds, de, bprivate) == 0) {
312: setDirective(PRIV);
313: priv = EMPTY_LIST;
314: } else if (HttpParser.compare(raw, ds, de, bnotransform) == 0) {
315: setDirective(NOTRANSFORM);
316: notransform = true;
317: } else if (HttpParser.compare(raw, ds, de, bmustrevalidate) == 0) {
318: setDirective(MUSTREVALIDATE);
319: mustrevalidate = true;
320: } else if (HttpParser.compare(raw, ds, de, bproxyrevalidate) == 0) {
321: setDirective(PROXYREVALIDATE);
322: proxyrevalidate = true;
323: } else {
324: if (extensions == null) {
325: extensions = new Vector(4);
326: extensions.add(new String(raw, 0, ds, de - ds));
327: }
328: // error("Unknown or invalid directive: "+new String(raw,0,ds,de));
329: }
330: }
331:
332: /**
333: * parse.
334: * @exception HttpParserException if parsing failed.
335: */
336: protected void parse() throws HttpParserException {
337: // Parse the raw value, this is the right time to do it:
338: ParseState ls = new ParseState(0);
339: ls.ioff = 0;
340: ls.bufend = raw.length;
341: ls.separator = (byte) ',';
342: ls.spaceIsSep = false; // gift for broken implementations
343: ParseState ld = new ParseState(0);
344: ld.separator = (byte) '=';
345: ld.spaceIsSep = false; // gift for broken implementations
346: // HttpParser.unquote(raw, ls);
347: while (HttpParser.nextItem(raw, ls) >= 0) {
348: ld.bufend = ls.end;
349: ld.ioff = ls.start;
350: if (HttpParser.nextItem(raw, ld) >= 0) {
351: int dstart = ld.start;
352: int dend = ld.end;
353: ld.prepare();
354: if (HttpParser.nextItem(raw, ld) >= 0)
355: parseDirective(dstart, dend, ld);
356: else
357: parseDirective(dstart, dend);
358: } else {
359: parseDirective(ls.start, ls.end);
360: }
361: ls.prepare();
362: }
363: }
364:
365: /**
366: * HeaderValue implementation - Get this header value.
367: * @return Itself !
368: */
369:
370: public Object getValue() {
371: validate();
372: return this ;
373: }
374:
375: /**
376: * Get and test the no-cache directive setting.
377: * @return A field-list as an array of String, or <strong>null</strong>
378: * if the directive is undefined.
379: */
380:
381: public String[] getNoCache() {
382: validate();
383: return checkDirective(NOCACHE) ? nocache : null;
384: }
385:
386: /**
387: * Set the no cache directive to the given list of fields.
388: * @param fields The fields to set in the no-cache directive, encoded
389: * as a String array (whose length can be <strong>0</strong>), or
390: * <strong>null</strong> to reset the value.
391: */
392:
393: public void setNoCache(String fields[]) {
394: validate();
395: if (fields == null) {
396: if (checkDirective(NOCACHE))
397: invalidateByteValue();
398: unsetDirective(NOCACHE);
399: } else {
400: setDirective(NOCACHE);
401: nocache = fields;
402: invalidateByteValue();
403: }
404: }
405:
406: /**
407: * Set the <code>no-cache</code> directive globally.
408: */
409:
410: public void setNoCache() {
411: validate();
412: setDirective(NOCACHE);
413: invalidateByteValue();
414: }
415:
416: /**
417: * Add the given header name to the <code>no-cache</code> directive.
418: * @param name The header name to add.
419: */
420:
421: public void addNoCache(String name) {
422: validate();
423: // If no-cache is set globally, then skip...
424: if (checkDirective(NOCACHE) && (nocache.length == 0))
425: return;
426: // Add or test for presence
427: if (nocache != null) {
428: // Check for that header name presence:
429: for (int i = 0; i < nocache.length; i++)
430: if (nocache[i].equalsIgnoreCase(name))
431: return;
432: invalidateByteValue();
433: String newcache[] = new String[nocache.length + 1];
434: System.arraycopy(nocache, 0, newcache, 0, nocache.length);
435: newcache[nocache.length] = name;
436: nocache = newcache;
437: } else {
438: invalidateByteValue();
439: nocache = new String[1];
440: nocache[0] = name;
441: }
442: setDirective(NOCACHE);
443: }
444:
445: /**
446: * Unset the <code>no-cache</code> directive.
447: */
448:
449: public void unsetNoCache() {
450: validate();
451: if (checkDirective(NOCACHE)) {
452: invalidateByteValue();
453: unsetDirective(NOCACHE);
454: nocache = null;
455: }
456: }
457:
458: /**
459: * Is the no-store flag set ?
460: * @return A boolean.
461: */
462:
463: public boolean checkNoStore() {
464: validate();
465: return checkDirective(NOSTORE) ? nostore : false;
466: }
467:
468: /**
469: * Set the <code>no-store</code> flag.
470: * @param onoff The value for the no-store directive.
471: */
472:
473: public void setNoStore(boolean onoff) {
474: validate();
475: if (onoff == false) {
476: if (nostore) {
477: invalidateByteValue();
478: nostore = false;
479: }
480: unsetDirective(NOSTORE);
481: } else if (!nostore) {
482: invalidateByteValue();
483: setDirective(NOSTORE);
484: nostore = true;
485: }
486: }
487:
488: /**
489: * Get the max-age value defined by this cache control policy.
490: * @return The max-age value, or <strong>-1</strong> if undefined.
491: */
492:
493: public final int getMaxAge() {
494: validate();
495: return checkDirective(MAXAGE) ? maxage : -1;
496: }
497:
498: /**
499: * Set the max-age directive for this cache control.
500: * @param age The max allowed age for the cache control policy, or
501: * <strong>-1</strong> to reset value.
502: */
503:
504: public void setMaxAge(int age) {
505: validate();
506: if (age == -1) {
507: if (checkDirective(MAXAGE))
508: invalidateByteValue();
509: maxage = -1;
510: unsetDirective(MAXAGE);
511: } else {
512: if ((age != maxage) || !checkDirective(MAXAGE))
513: invalidateByteValue();
514: setDirective(MAXAGE);
515: maxage = age;
516: }
517: }
518:
519: /**
520: * Get the s-maxage value defined by this cache control policy.
521: * @return The s-maxage value, or <strong>-1</strong> if undefined.
522: */
523: public final int getSMaxAge() {
524: validate();
525: return checkDirective(S_MAXAGE) ? s_maxage : -1;
526: }
527:
528: /**
529: * Set the s_maxage directive for this cache control.
530: * @param age The max allowed age for the cache control policy, or
531: * <strong>-1</strong> to reset value.
532: */
533: public void setSMaxAge(int age) {
534: validate();
535: if (age == -1) {
536: if (checkDirective(S_MAXAGE))
537: invalidateByteValue();
538: s_maxage = -1;
539: unsetDirective(S_MAXAGE);
540: } else {
541: if ((age != s_maxage) || !checkDirective(S_MAXAGE))
542: invalidateByteValue();
543: setDirective(S_MAXAGE);
544: s_maxage = age;
545: }
546: }
547:
548: /**
549: * Get the max-stale value defined by this control object.
550: * @return The max-stale value, or <strong>-1</strong> if undefined.
551: */
552:
553: public int getMaxStale() {
554: validate();
555: return checkDirective(MAXSTALE) ? maxstale : -1;
556: }
557:
558: /**
559: * Set the max-stale directive value.
560: * @param stale The max-stale value, or <strong>-1</strong> to reset value.
561: */
562:
563: public void setMaxStale(int stale) {
564: validate();
565: if (stale == -1) {
566: if (checkDirective(MAXSTALE))
567: invalidateByteValue();
568: maxstale = -1;
569: unsetDirective(MAXSTALE);
570: } else {
571: if ((stale != maxstale) || !checkDirective(MAXSTALE))
572: invalidateByteValue();
573: setDirective(MAXSTALE);
574: maxstale = stale;
575: }
576: }
577:
578: /**
579: * Get the min-fresh directive value.
580: * @param def The default value to reurn if undefined.
581: */
582:
583: public int getMinFresh() {
584: validate();
585: return checkDirective(MINFRESH) ? minfresh : -1;
586: }
587:
588: /**
589: * Set the minfresh directive value.
590: * @param fresh The new minfresh value, or <strong>-1</strong> to reset
591: * value.
592: */
593:
594: public void setMinFresh(int fresh) {
595: validate();
596: if (fresh == -1) {
597: if (checkDirective(MINFRESH))
598: invalidateByteValue();
599: minfresh = -1;
600: unsetDirective(MINFRESH);
601: } else {
602: if ((fresh != minfresh) || !checkDirective(MINFRESH))
603: invalidateByteValue();
604: setDirective(MINFRESH);
605: minfresh = fresh;
606: }
607: }
608:
609: /**
610: * Is the on-if-cached flag value set ?
611: * @return A boolean.
612: */
613:
614: public boolean checkOnlyIfCached() {
615: validate();
616: return onlyifcached;
617: }
618:
619: /**
620: * Set the only-if-cached directive.
621: * @param onoff The boolean value for the directive.
622: */
623:
624: public void setOnlyIfCached(boolean onoff) {
625: validate();
626: if (!onoff) {
627: if (onlyifcached) {
628: invalidateByteValue();
629: onlyifcached = false;
630: }
631: unsetDirective(ONLYIFCACHED);
632: } else if (!onlyifcached) {
633: invalidateByteValue();
634: setDirective(ONLYIFCACHED);
635: onlyifcached = true;
636: }
637: }
638:
639: /**
640: * Is the public flag set ?
641: * @return A boolean.
642: */
643:
644: public boolean checkPublic() {
645: validate();
646: return pub;
647: }
648:
649: /**
650: * Set the public directive.
651: * @param onoff The public directive value.
652: */
653:
654: public void setPublic(boolean onoff) {
655: validate();
656: if (!onoff) {
657: if (pub) {
658: invalidateByteValue();
659: pub = false;
660: }
661: unsetDirective(PUB);
662: } else if (!pub) {
663: invalidateByteValue();
664: setDirective(PUB);
665: pub = true;
666: }
667: }
668:
669: /**
670: * Check and get the private value.
671: * @param def The default value if undefined.
672: * @return A list of field-names, as a String array, or the provided
673: * default value otherwise.
674: */
675:
676: public String[] getPrivate() {
677: validate();
678: return (priv == null) ? null : priv;
679: }
680:
681: /**
682: * Set the private directive value.
683: * @param priv The list of field-names as a String array.
684: */
685:
686: public void setPrivate(String priv[]) {
687: validate();
688: invalidateByteValue();
689: setDirective(PRIV);
690: this .priv = priv;
691: }
692:
693: /**
694: * Unset the <code>private</code> directive.
695: */
696:
697: public void unsetPrivate() {
698: validate();
699: if (checkDirective(PRIV))
700: invalidateByteValue();
701: unsetDirective(PRIV);
702: priv = null;
703: }
704:
705: /**
706: * Is the no-transform flag set ?
707: * @return A boolean.
708: */
709:
710: public boolean checkNoTransform() {
711: validate();
712: return notransform;
713: }
714:
715: /**
716: * Set the no-transform directive.
717: * @param onoff The new boolean value for the no-transform directive.
718: */
719:
720: public void setNoTransform(boolean onoff) {
721: validate();
722: if (!onoff) {
723: if (notransform) {
724: invalidateByteValue();
725: notransform = false;
726: }
727: unsetDirective(NOTRANSFORM);
728: } else if (!notransform) {
729: invalidateByteValue();
730: setDirective(NOTRANSFORM);
731: notransform = true;
732: }
733: }
734:
735: /**
736: * Is the must-revalidate flag set ?
737: * @return A boolean.
738: */
739:
740: public boolean checkMustRevalidate() {
741: validate();
742: return mustrevalidate;
743: }
744:
745: /**
746: * Set the must-revalidate directive.
747: * @param onoff The new value for the must-revalidate directive.
748: */
749:
750: public void setMustRevalidate(boolean onoff) {
751: validate();
752: if (!onoff) {
753: if (mustrevalidate) {
754: invalidateByteValue();
755: mustrevalidate = false;
756: }
757: unsetDirective(MUSTREVALIDATE);
758: } else if (!mustrevalidate) {
759: invalidateByteValue();
760: setDirective(MUSTREVALIDATE);
761: mustrevalidate = true;
762: }
763: }
764:
765: /**
766: * Is the proxy-revalidate flag set ?
767: * @return A boolean.
768: */
769:
770: public boolean checkProxyRevalidate() {
771: validate();
772: return proxyrevalidate;
773: }
774:
775: /**
776: * Set the proxy-revalidate directive.
777: * @param onoff The new proxy-revalidate value.
778: */
779:
780: public void setProxyRevalidate(boolean onoff) {
781: validate();
782: if (!onoff) {
783: if (proxyrevalidate) {
784: invalidateByteValue();
785: proxyrevalidate = false;
786: }
787: unsetDirective(PROXYREVALIDATE);
788: } else if (!proxyrevalidate) {
789: invalidateByteValue();
790: setDirective(PROXYREVALIDATE);
791: proxyrevalidate = true;
792: }
793: }
794:
795: /**
796: * Create a new empty HttpCacheControl object descriptor.
797: * @param isValid A boolean indicating if this object will be filled in
798: * by parsing a value, or is for internal purposes.
799: */
800:
801: HttpCacheControl(boolean isValid) {
802: this .raw = null;
803: this .isValid = isValid;
804: }
805:
806: /**
807: * Create a new empty cache control object descriptor.
808: * The value will be provided through parsing.
809: */
810:
811: public HttpCacheControl() {
812: this (false);
813: }
814:
815: }
|