Changeset 879
- Timestamp:
- 10/15/12 14:53:44 (12 years ago)
- Location:
- trunk/autoquest-htmlmonitor
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-htmlmonitor
-
Property
svn:ignore
set to
target
-
Property
svn:ignore
set to
-
trunk/autoquest-htmlmonitor/pom.xml
r867 r879 53 53 </dependencies> 54 54 <build> 55 <resources> 56 <resource> 57 <directory>src/main/js</directory> 58 </resource> 59 </resources> 55 60 <extensions> 56 61 <extension> -
trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorServer.java
r874 r879 9 9 /** 10 10 * <p> 11 * this is the web server, that receives the client messages. It is initialized with a port on 12 * which it shall listen, as well as a message listener to forward the received messages to. 13 * Internally it starts a jetty web server with a single {@link HtmlMonitorServlet} to receive 14 * the messages. 11 * this is the web server, that receives the client messages. It also provides the java script 12 * that is used by the client via the URL /script/autoquest-htmlmonitor.js. It is initialized 13 * with a port on which it shall listen, as well as a message listener to forward the received 14 * messages to. Internally it starts a jetty web server with a single {@link HtmlMonitorServlet} 15 * to receive the messages as well as a . 15 16 * </p> 16 17 * -
trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorServlet.java
r873 r879 1 1 package de.ugoe.cs.autoquest.htmlmonitor; 2 2 3 import java.io.BufferedReader; 3 4 import java.io.IOException; 5 import java.io.InputStream; 4 6 import java.io.InputStreamReader; 7 import java.io.PrintWriter; 5 8 import java.net.MalformedURLException; 6 9 import java.net.URL; … … 24 27 /** 25 28 * <p> 26 * the servlet deployed in the web server that receives all client messages. The messages are 27 * parsed, validated, and forwarded to the provided message listener. If a message is not valid, 28 * it is discarded. If an event in a message is not valid, it is discarded. Messages are only 29 * received via the POST HTTP method. 29 * the servlet deployed in the web server that receives all client messages and returns the client 30 * java script. The messages are parsed, validated, and forwarded to the provided message listener. 31 * If a message is not valid, it is discarded. If an event in a message is not valid, it is 32 * discarded. Messages are only received via the POST HTTP method. The GET HTTP method is only 33 * implemented for returning the client java script. 30 34 * </p> 31 35 * … … 37 41 private static final long serialVersionUID = 1L; 38 42 43 /** */ 44 private static final boolean DO_TRACE = false; 45 39 46 /** 40 47 * the message listener to forward received messages to. … … 51 58 HtmlMonitorServlet(HtmlMonitorMessageListener messageListener) { 52 59 this.messageListener = messageListener; 60 } 61 62 /* (non-Javadoc) 63 * @see org.mortbay.jetty.servlet.DefaultServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 64 */ 65 @Override 66 protected void doGet(HttpServletRequest request, HttpServletResponse response) 67 throws ServletException, IOException 68 { 69 if ((request.getPathInfo() != null) && 70 (request.getPathInfo().endsWith("/script/autoquest-htmlmonitor.js"))) 71 { 72 InputStream script = null; 73 74 try { 75 script = this.getClass().getClassLoader().getResourceAsStream 76 ("autoquest-htmlmonitor.js"); 77 78 if (script == null) { 79 Console.printerrln("could not read autoquest-htmlmonitor.js from classpath"); 80 } 81 else { 82 BufferedReader reader = new BufferedReader(new InputStreamReader(script)); 83 PrintWriter output = response.getWriter(); 84 String line; 85 86 while ((line = reader.readLine()) != null) { 87 output.println(line); 88 } 89 90 output.close(); 91 } 92 } 93 catch (Exception e) { 94 Console.printerrln("could not read autoquest-htmlmonitor.js from classpath: " + e); 95 Console.logException(e); 96 } 97 finally { 98 if (script != null) { 99 script.close(); 100 } 101 } 102 } 53 103 } 54 104 … … 87 137 */ 88 138 private void handleJSONObject(JSONObject object) { 89 dumpJSONObject(object, ""); 139 if (DO_TRACE) { 140 dumpJSONObject(object, ""); 141 } 90 142 91 143 JSONObject message = assertValue(object, "message", JSONObject.class); -
trunk/autoquest-htmlmonitor/src/main/js/autoquest-htmlmonitor.js
r876 r879 25 25 * the server to send the recorded data to 26 26 */ 27 var destination = "http://localhost:8090"; // change to the location of your server27 var autoquestDestination; 28 28 29 29 /** 30 30 * the maximum number of recorded events to be put into one package sent to the server 31 31 */ 32 var packageSize = 10;32 var autoquestPackageSize = 10; 33 33 34 34 /** … … 36 36 * event handling action to be monitored 37 37 */ 38 var a ctionConfig = [38 var autoquestActionConfig = [ 39 39 { "tag": "body", "actions": [ "onunload", "onscroll" ] }, 40 40 { "tag": "a", "actions": [ "onclick", "ondblclick", "onfocus" ] }, … … 45 45 * a possibility to trace, what is going on 46 46 */ 47 var doLog = false;47 var autoquestDoLog = false; 48 48 49 49 /*var matchedTags = ["A", "ABBR", "ACRONYM", "ADDRESS", "AREA", "B", "BIG", "BLOCKQUOTE", "BODY", … … 61 61 * stores events, which were recorded but not sent to the server yet 62 62 */ 63 var recordedEvents = [];63 var autoquestRecordedEvents = []; 64 64 65 65 /** … … 77 77 if (document.body) { 78 78 log("adding event handling attributes"); 79 determineDestination(); 79 80 addEventHandlingAttributes(document.documentElement, ""); 80 81 … … 90 91 91 92 /** 92 * traverses the DOM-structure of the HTML-site, and adds event handling attributes to each 93 * traverses the DOM-structure of the HTML-site and determines the URL of this script. Based on 94 * this URL, it calculates the destination to which the traced interactions must be sent 95 */ 96 function determineDestination() { 97 var scriptElements = document.getElementsByTagName("script"); 98 var i; 99 var index; 100 101 for (i = 0; i < scriptElements.length; i++) { 102 if ((scriptElements[i].type === "text/javascript") && (scriptElements[i].src)) { 103 index = scriptElements[i].src.lastIndexOf("script/autoquest-htmlmonitor.js"); 104 if (index > -1) { 105 autoquestDestination = scriptElements[i].src.substring(0, index - 1); 106 log("using destination " + autoquestDestination); 107 } 108 } 109 } 110 } 111 112 /** 113 * traverses the DOM-structure of the HTML-site and adds event handling attributes to each 93 114 * relevant node 94 115 * … … 105 126 106 127 if (node.nodeType === Node.ELEMENT_NODE) { 107 for (i = 0; i < a ctionConfig.length; i++) {108 if (node.tagName.toLowerCase() === a ctionConfig[i].tag.toLowerCase()) {109 for (k = 0; k < a ctionConfig[i].actions.length; k++) {110 value = "handleEvent('" + a ctionConfig[i].actions[k] + "', '" + nodePath+111 "', event);";112 113 if (!node.getAttribute(a ctionConfig[i].actions[k])) {114 node.setAttribute(a ctionConfig[i].actions[k], value);128 for (i = 0; i < autoquestActionConfig.length; i++) { 129 if (node.tagName.toLowerCase() === autoquestActionConfig[i].tag.toLowerCase()) { 130 for (k = 0; k < autoquestActionConfig[i].actions.length; k++) { 131 value = "handleEvent('" + autoquestActionConfig[i].actions[k] + "', '" + 132 nodePath + "', event);"; 133 134 if (!node.getAttribute(autoquestActionConfig[i].actions[k])) { 135 node.setAttribute(autoquestActionConfig[i].actions[k], value); 115 136 } 116 137 else { 117 var oldValue = node.getAttribute(a ctionConfig[i].actions[k]);138 var oldValue = node.getAttribute(autoquestActionConfig[i].actions[k]); 118 139 if (oldValue.indexOf(value) < 0) { 119 node.setAttribute(actionConfig[i].actions[k], value + ' ' + oldValue); 140 node.setAttribute(autoquestActionConfig[i].actions[k], 141 value + ' ' + oldValue); 120 142 } 121 143 } … … 189 211 * of the nodes. These attributes are generated by the 190 212 * {@link #addEventHandlingAttributes(node,parentPath)} function. It creates a new Event object and 191 * add it to the list of <code> recordedEvents</code>. If this list achieves the maximum192 * <code> packageSize</code> the events in the list are sent to the server asynchronously through193 * calling {@link #sendRequest()}.213 * add it to the list of <code>autoquestRecordedEvents</code>. If this list achieves the maximum 214 * <code>autoquestPackageSize</code> the events in the list are sent to the server asynchronously 215 * through calling {@link #sendRequest()}. 194 216 * 195 217 * @param eventName the name of the event, e.g. onscroll … … 198 220 */ 199 221 function handleEvent(eventName, nodePath, event) { 222 log("handling event " + eventName); 223 224 if (!autoquestDestination) { 225 // do nothing if we have no destination to send data to 226 return; 227 } 228 200 229 var eventType = eventName.toLowerCase(); 201 230 202 var eventObj = recordedEvents.pop();231 var eventObj = autoquestRecordedEvents.pop(); 203 232 204 233 // reuse previous on scroll events to prevent too many events 205 234 if ((eventName !== "onscroll") || (!eventObj) || (eventObj.type !== "onscroll")) { 206 235 if (eventObj) { 207 recordedEvents.push(eventObj);236 autoquestRecordedEvents.push(eventObj); 208 237 } 209 238 eventObj = new Event(eventType, nodePath); … … 224 253 } 225 254 226 recordedEvents.push(eventObj); 227 228 if ((recordedEvents.length >= packageSize) || (eventType === "onunload")) { 255 log("storing event " + eventName); 256 autoquestRecordedEvents.push(eventObj); 257 258 if (autoquestRecordedEvents.length >= autoquestPackageSize) { 259 log("initiating sending events"); 229 260 setTimeout(sendRequest, 100); 230 261 } 262 else if (eventType === "onunload") { 263 log("initiating sending events"); 264 sendRequest(); 265 } 231 266 232 267 } … … 234 269 /** 235 270 * sends the collected data to the server, named in the destination-variable. For this it generates 236 * a JSON formatted message and uses Ajax and the <code>destination</code> to send it to the server 271 * a JSON formatted message and uses Ajax and the <code>autoquestDestination</code> to send it to 272 * the server 237 273 */ 238 274 function sendRequest() { … … 243 279 var request; 244 280 245 if (recordedEvents.length > 0) { 246 eventList = recordedEvents; 247 recordedEvents = []; 281 if (autoquestRecordedEvents.length > 0) { 282 log("creating message"); 283 eventList = autoquestRecordedEvents; 284 autoquestRecordedEvents = []; 248 285 249 286 message = "{\"message\":{\"clientInfos\":{"; … … 283 320 } 284 321 285 request.open("POST", destination, true); 322 log("sending message"); 323 request.open("POST", autoquestDestination, true); 286 324 287 325 log("sending " + message); … … 434 472 */ 435 473 function log(text) { 436 if ( doLog) {474 if (autoquestDoLog) { 437 475 var loggingInfo = document.getElementById("loggingInfoParagraph"); 438 476
Note: See TracChangeset
for help on using the changeset viewer.