001: package wicket.markup.html;
002:
003: import java.util.HashMap;
004: import java.util.Map;
005:
006: import org.apache.commons.logging.Log;
007: import org.apache.commons.logging.LogFactory;
008:
009: import wicket.Application;
010: import wicket.IResponseFilter;
011: import wicket.RequestCycle;
012: import wicket.Session;
013: import wicket.model.Model;
014: import wicket.util.string.AppendingStringBuffer;
015: import wicket.util.string.JavascriptUtils;
016:
017: /**
018: * This is a filter that injects javascript code to the top head portion and
019: * after the body so that the time can me measured what the client parse time
020: * was for this page. It also reports the total server parse/response time in
021: * the client and logs the server response time and response size it took for a
022: * specific response in the server log.
023: *
024: * You can specify what the status text should be like this:
025: * ServerAndClientTimeFilter.statustext=My Application, Server parsetime:
026: * ${servertime}, Client parsetime: ${clienttime} likewise for ajax request use
027: * ajax.ServerAndClientTimeFilter.statustext
028: *
029: * @author jcompagner
030: */
031: public class AjaxServerAndClientTimeFilter implements IResponseFilter {
032: private static Log log = LogFactory
033: .getLog(AjaxServerAndClientTimeFilter.class);
034:
035: /**
036: * @see wicket.IResponseFilter#filter(java.lang.StringBuffer)
037: */
038: public AppendingStringBuffer filter(
039: AppendingStringBuffer responseBuffer) {
040: int headIndex = responseBuffer.indexOf("<head>");
041: int bodyIndex = responseBuffer.indexOf("</body>");
042: int ajaxStart = responseBuffer.indexOf("<ajax-response>");
043: int ajaxEnd = responseBuffer.indexOf("</ajax-response>");
044: long timeTaken = System.currentTimeMillis()
045: - RequestCycle.get().getStartTime();
046: if (headIndex != -1 && bodyIndex != -1) {
047: AppendingStringBuffer endScript = new AppendingStringBuffer(
048: 150);
049: endScript.append("\n").append(
050: JavascriptUtils.SCRIPT_OPEN_TAG);
051: endScript.append("\nwindow.defaultStatus='");
052: endScript.append(getStatusString(timeTaken,
053: "ServerAndClientTimeFilter.statustext"));
054: endScript.append("';\n").append(
055: JavascriptUtils.SCRIPT_CLOSE_TAG).append("\n");
056: responseBuffer.insert(bodyIndex - 1, endScript);
057: responseBuffer
058: .insert(
059: headIndex + 6,
060: "\n"
061: + JavascriptUtils.SCRIPT_OPEN_TAG
062: + "\nvar clientTimeVariable = new Date().getTime();\n"
063: + JavascriptUtils.SCRIPT_CLOSE_TAG
064: + "\n");
065: } else if (ajaxStart != -1 && ajaxEnd != -1) {
066: AppendingStringBuffer startScript = new AppendingStringBuffer(
067: 250);
068: startScript
069: .append("<evaluate><![CDATA[window.defaultStatus='");
070: startScript.append(getStatusString(timeTaken,
071: "ajax.ServerAndClientTimeFilter.statustext"));
072: startScript.append("';]]></evaluate>");
073: responseBuffer.insert(ajaxEnd, startScript.toString());
074: responseBuffer
075: .insert(ajaxStart + 15,
076: "<evaluate><![CDATA[clientTimeVariable = new Date().getTime();]]></evaluate>");
077: }
078: log.info(timeTaken + "ms server time taken for request "
079: + RequestCycle.get().getRequest().getURL()
080: + " response size: " + responseBuffer.length());
081: return responseBuffer;
082: }
083:
084: /**
085: * Returns a locale specific status message about the server and client
086: * time.
087: *
088: * @param timeTaken
089: * the server time it took
090: * @param resourceKey
091: * The key for the locale specific string lookup
092: * @return String with the status message
093: */
094: private String getStatusString(long timeTaken, String resourceKey) {
095: Map map = new HashMap(4);
096: map
097: .put("clienttime",
098: "' + (new Date().getTime() - clientTimeVariable)/1000 + 's");
099: map.put("servertime", ((double) timeTaken) / 1000 + "s");
100: AppendingStringBuffer defaultValue = new AppendingStringBuffer(
101: 128);
102: defaultValue.append("Server parsetime: ");
103: defaultValue.append(((double) timeTaken) / 1000);
104: defaultValue
105: .append("s, Client parsetime: ' + (new Date().getTime() - clientTimeVariable)/1000 + 's");
106: String txt = Application.get().getResourceSettings()
107: .getLocalizer().getString(resourceKey, null,
108: Model.valueOf(map), Session.get().getLocale(),
109: Session.get().getStyle(),
110: defaultValue.toString());
111: return txt;
112: }
113: }
|