Ignore:
Timestamp:
10/15/12 14:53:44 (12 years ago)
Author:
pharms
Message:
  • changed implementation so that java script is served by server itself and that it determines the servers location through its own URL
Location:
trunk/autoquest-htmlmonitor
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-htmlmonitor

    • Property svn:ignore set to
      target
  • trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorServer.java

    r874 r879  
    99/** 
    1010 * <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 . 
    1516 * </p> 
    1617 *  
  • trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorServlet.java

    r873 r879  
    11package de.ugoe.cs.autoquest.htmlmonitor; 
    22 
     3import java.io.BufferedReader; 
    34import java.io.IOException; 
     5import java.io.InputStream; 
    46import java.io.InputStreamReader; 
     7import java.io.PrintWriter; 
    58import java.net.MalformedURLException; 
    69import java.net.URL; 
     
    2427/** 
    2528 * <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. 
    3034 * </p> 
    3135 *  
     
    3741    private static final long serialVersionUID = 1L; 
    3842     
     43    /**  */ 
     44    private static final boolean DO_TRACE = false; 
     45     
    3946    /** 
    4047     * the message listener to forward received messages to. 
     
    5158    HtmlMonitorServlet(HtmlMonitorMessageListener messageListener) { 
    5259        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        } 
    53103    } 
    54104 
     
    87137     */ 
    88138    private void handleJSONObject(JSONObject object) { 
    89         dumpJSONObject(object, ""); 
     139        if (DO_TRACE) { 
     140            dumpJSONObject(object, ""); 
     141        } 
    90142         
    91143        JSONObject message = assertValue(object, "message", JSONObject.class); 
  • trunk/autoquest-htmlmonitor/src/main/js/autoquest-htmlmonitor.js

    r876 r879  
    2525 * the server to send the recorded data to 
    2626 */ 
    27 var destination = "http://localhost:8090"; // change to the location of your server 
     27var autoquestDestination; 
    2828 
    2929/** 
    3030 * the maximum number of recorded events to be put into one package sent to the server 
    3131 */ 
    32 var packageSize = 10; 
     32var autoquestPackageSize = 10; 
    3333 
    3434/** 
     
    3636 * event handling action to be monitored 
    3737 */ 
    38 var actionConfig = [ 
     38var autoquestActionConfig = [ 
    3939    { "tag": "body", "actions": [ "onunload", "onscroll" ] }, 
    4040    { "tag": "a", "actions": [ "onclick", "ondblclick", "onfocus" ] }, 
     
    4545 * a possibility to trace, what is going on 
    4646 */ 
    47 var doLog = false; 
     47var autoquestDoLog = false; 
    4848 
    4949/*var matchedTags = ["A", "ABBR", "ACRONYM", "ADDRESS", "AREA", "B", "BIG", "BLOCKQUOTE", "BODY", 
     
    6161 * stores events, which were recorded but not sent to the server yet 
    6262 */ 
    63 var recordedEvents = []; 
     63var autoquestRecordedEvents = []; 
    6464 
    6565/** 
     
    7777    if (document.body) { 
    7878        log("adding event handling attributes"); 
     79        determineDestination(); 
    7980        addEventHandlingAttributes(document.documentElement, ""); 
    8081         
     
    9091 
    9192/** 
    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 */ 
     96function 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 
    93114 * relevant node 
    94115 *  
     
    105126     
    106127    if (node.nodeType === Node.ELEMENT_NODE) { 
    107         for (i = 0; i < actionConfig.length; i++) { 
    108             if (node.tagName.toLowerCase() === actionConfig[i].tag.toLowerCase()) { 
    109                 for (k = 0; k < actionConfig[i].actions.length; k++) { 
    110                     value = "handleEvent('" + actionConfig[i].actions[k] + "', '" + nodePath + 
    111                         "', event);"; 
    112  
    113                     if (!node.getAttribute(actionConfig[i].actions[k])) { 
    114                         node.setAttribute(actionConfig[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); 
    115136                    } 
    116137                    else { 
    117                         var oldValue = node.getAttribute(actionConfig[i].actions[k]); 
     138                        var oldValue = node.getAttribute(autoquestActionConfig[i].actions[k]); 
    118139                        if (oldValue.indexOf(value) < 0) { 
    119                             node.setAttribute(actionConfig[i].actions[k], value + ' ' + oldValue); 
     140                            node.setAttribute(autoquestActionConfig[i].actions[k], 
     141                                              value + ' ' + oldValue); 
    120142                        } 
    121143                    } 
     
    189211 * of the nodes. These attributes are generated by the 
    190212 * {@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 maximum 
    192  * <code>packageSize</code> the events in the list are sent to the server asynchronously through 
    193  * 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()}. 
    194216 *  
    195217 * @param eventName the name of the event, e.g. onscroll 
     
    198220 */ 
    199221function 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     
    200229    var eventType = eventName.toLowerCase(); 
    201230     
    202     var eventObj = recordedEvents.pop(); 
     231    var eventObj = autoquestRecordedEvents.pop(); 
    203232     
    204233    // reuse previous on scroll events to prevent too many events 
    205234    if ((eventName !== "onscroll") || (!eventObj) || (eventObj.type !== "onscroll")) { 
    206235        if (eventObj) { 
    207             recordedEvents.push(eventObj); 
     236            autoquestRecordedEvents.push(eventObj); 
    208237        } 
    209238        eventObj = new Event(eventType, nodePath); 
     
    224253    } 
    225254 
    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"); 
    229260        setTimeout(sendRequest, 100); 
    230261    } 
     262    else if (eventType === "onunload") { 
     263        log("initiating sending events"); 
     264        sendRequest(); 
     265    } 
    231266 
    232267} 
     
    234269/** 
    235270 * 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 
    237273 */ 
    238274function sendRequest() { 
     
    243279    var request; 
    244280     
    245     if (recordedEvents.length > 0) { 
    246         eventList = recordedEvents; 
    247         recordedEvents = []; 
     281    if (autoquestRecordedEvents.length > 0) { 
     282        log("creating message"); 
     283        eventList = autoquestRecordedEvents; 
     284        autoquestRecordedEvents = []; 
    248285         
    249286        message = "{\"message\":{\"clientInfos\":{"; 
     
    283320        } 
    284321         
    285         request.open("POST", destination, true); 
     322        log("sending message"); 
     323        request.open("POST", autoquestDestination, true); 
    286324 
    287325        log("sending " + message); 
     
    434472 */ 
    435473function log(text) { 
    436     if (doLog) { 
     474    if (autoquestDoLog) { 
    437475        var loggingInfo = document.getElementById("loggingInfoParagraph"); 
    438476         
Note: See TracChangeset for help on using the changeset viewer.