01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one or more
03: * contributor license agreements. See the NOTICE file distributed with
04: * this work for additional information regarding copyright ownership.
05: * The ASF licenses this file to You under the Apache License, Version 2.0
06: * (the "License"); you may not use this file except in compliance with
07: * the License. You may obtain a copy of the License at
08: *
09: * http://www.apache.org/licenses/LICENSE-2.0
10: *
11: * Unless required by applicable law or agreed to in writing, software
12: * distributed under the License is distributed on an "AS IS" BASIS,
13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14: * See the License for the specific language governing permissions and
15: * limitations under the License.
16: */
17: package org.apache.wicket.markup.html;
18:
19: import java.util.HashMap;
20: import java.util.Map;
21:
22: import org.apache.wicket.Application;
23: import org.apache.wicket.IResponseFilter;
24: import org.apache.wicket.RequestCycle;
25: import org.apache.wicket.model.Model;
26: import org.apache.wicket.util.string.AppendingStringBuffer;
27: import org.apache.wicket.util.string.JavascriptUtils;
28: import org.slf4j.Logger;
29: import org.slf4j.LoggerFactory;
30:
31: /**
32: * This is a filter that injects javascript code to the top head portion and
33: * after the body so that the time can me measured what the client parse time
34: * was for this page. It also reports the total server parse/response time in
35: * the client and logs the server response time and response size it took for a
36: * specific response in the server log.
37: *
38: * You can specify what the status text should be like this:
39: * ServerAndClientTimeFilter.statustext=My Application, Server parsetime:
40: * ${servertime}, Client parsetime: ${clienttime}
41: *
42: * @author jcompagner
43: */
44: public class ServerAndClientTimeFilter implements IResponseFilter {
45: private static final Logger log = LoggerFactory
46: .getLogger(ServerAndClientTimeFilter.class);
47:
48: /**
49: * @see org.apache.wicket.IResponseFilter#filter(AppendingStringBuffer)
50: */
51: public AppendingStringBuffer filter(
52: AppendingStringBuffer responseBuffer) {
53: int headIndex = responseBuffer.indexOf("<head>");
54: int bodyIndex = responseBuffer.indexOf("</body>");
55: long timeTaken = System.currentTimeMillis()
56: - RequestCycle.get().getStartTime();
57: if (headIndex != -1 && bodyIndex != -1) {
58: Map map = new HashMap(4);
59: map
60: .put("clienttime",
61: "' + (new Date().getTime() - clientTimeVariable)/1000 + 's");
62: map.put("servertime", ((double) timeTaken) / 1000 + "s");
63:
64: AppendingStringBuffer defaultValue = new AppendingStringBuffer(
65: 128);
66: defaultValue.append("Server parsetime: ");
67: defaultValue.append(((double) timeTaken) / 1000);
68: defaultValue
69: .append("s, Client parsetime: ' + (new Date().getTime() - clientTimeVariable)/1000 + 's");
70:
71: String txt = Application.get().getResourceSettings()
72: .getLocalizer().getString(
73: "ServerAndClientTimeFilter.statustext",
74: null, Model.valueOf(map),
75: defaultValue.toString());
76: AppendingStringBuffer endScript = new AppendingStringBuffer(
77: 150);
78: endScript.append("\n").append(
79: JavascriptUtils.SCRIPT_OPEN_TAG);
80: endScript.append("\nwindow.defaultStatus='");
81: endScript.append(txt);
82: endScript.append("';\n").append(
83: JavascriptUtils.SCRIPT_CLOSE_TAG).append("\n");
84: responseBuffer.insert(bodyIndex - 1, endScript);
85: responseBuffer
86: .insert(
87: headIndex + 6,
88: "\n"
89: + JavascriptUtils.SCRIPT_OPEN_TAG
90: + "\nvar clientTimeVariable = new Date().getTime();\n"
91: + JavascriptUtils.SCRIPT_CLOSE_TAG
92: + "\n");
93: }
94: log.info(timeTaken + "ms server time taken for request "
95: + RequestCycle.get().getRequest().getURL()
96: + " response size: " + responseBuffer.length());
97: return responseBuffer;
98: }
99: }
|