001: /*
002: * ModifiedTemplate.java
003: *
004: * Brazil project web application Framework,
005: * export version: 1.1
006: * Copyright (c) 2000 Sun Microsystems, Inc.
007: *
008: * Sun Public License Notice
009: *
010: * The contents of this file are subject to the Sun Public License Version
011: * 1.0 (the "License"). You may not use this file except in compliance with
012: * the License. A copy of the License is included as the file "license.terms",
013: * and also available at http://www.sun.com/
014: *
015: * The Original Code is from:
016: * Brazil project web application Framework release 1.1.
017: * The Initial Developer of the Original Code is: suhler.
018: * Portions created by suhler are Copyright (C) Sun Microsystems, Inc.
019: * All Rights Reserved.
020: *
021: * Contributor(s): suhler.
022: *
023: * Version: 1.3
024: * Created by suhler on 00/11/19
025: * Last modified by suhler on 00/12/11 13:31:16
026: */
027:
028: package sunlabs.brazil.template;
029:
030: import sunlabs.brazil.util.http.HttpUtil;
031: import sunlabs.brazil.server.Server;
032: import java.io.Serializable;
033:
034: /**
035: * Template class for computing <code>last-modified</code> times
036: * for content that is processed through templates.
037: * <p>
038: * For traditional web content that is stored in a file, it is easy to
039: * keep track of the last time the content changed, simply by looking at the
040: * modify-time attribute of the file. Many browsers (and caches) use
041: * this information,
042: * obtained from the <code>last-modified</code> http header to determine
043: * whether to use an existing copy of the document, or a cached copy.
044: * <p>
045: * When the content is dynamically transformed, however, the last modified
046: * time is more complex: a combination of the original file modification
047: * time combined with the last change made to the transformation
048: * parameters.
049: * <p>
050: * A new HTML tag,
051: * <code><modified></code> is defined, and is intended to be
052: * used in conjunction with the BSLTemplate. When present in a
053: * page, the <code>last-modified</code> time of the transformation
054: * is set to the server's current time. When the content is delivered
055: * to the client, the <code>last-modified</code> header is set to the
056: * more recent of the origin last-modified time and the transformation
057: * modified time.
058: * <p>
059: * Properties:
060: * <dl class=props>
061: * <dt> debug
062: * <dd> If this configuration parameter is present, <code>modified</code>
063: * tag is replaced by a comment. Otherwise it is removed from the document.
064: * </dl>
065: *
066: * @author Stephen Uhler
067: * @version %V% 00/12/11
068: */
069:
070: public class ModifiedTemplate extends Template implements Serializable {
071:
072: private static final String DEBUG = "debug";
073: transient boolean debug;
074: long modified = 0; // last modified time of session transformation
075:
076: public boolean init(RewriteContext hr) {
077: debug = (hr.request.props.getProperty(hr.prefix + DEBUG) != null);
078: return true;
079: }
080:
081: /**
082: * Set the content transformation modifiy time to NOW
083: */
084:
085: public void tag_modified(RewriteContext hr) {
086: modified = hr.request.startMillis;
087: hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix
088: + "setting transform modified time: " + modified);
089: hr.killToken();
090: if (debug) {
091: hr.append("<!-- " + hr.getBody() + " -->");
092: }
093: }
094:
095: /**
096: * Compute the http last modified value by comparing the origin
097: * last-modified value (if any) with the transform value
098: */
099:
100: public boolean done(RewriteContext hr) {
101: if (modified == 0) {
102: modified = hr.request.startMillis;
103: }
104: /*
105:
106: * Find the last-mod time from the origin document. Look
107: * in the request props first.
108: */
109:
110: long originTime;
111: String propsTime = hr.request.props.getProperty("lastModified");
112: if (propsTime == null) {
113: originTime = HttpUtil.parseTime(hr.request.responseHeaders
114: .get("last-modified"));
115: } else {
116: originTime = Long.parseLong(propsTime);
117: }
118:
119: /*
120: * Muck with the last-modified header, only if we need to
121: */
122:
123: if (originTime < modified) {
124: hr.request.responseHeaders.remove("last-modified");
125: hr.request.addHeader("Last-Modified", HttpUtil
126: .formatTime(modified));
127: hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix
128: + "Adjusting mod time: " + originTime + " -> "
129: + modified);
130: }
131:
132: return true;
133: }
134: }
|