Ignore:
Timestamp:
12/14/12 15:10:12 (12 years ago)
Author:
pharms
Message:
  • changed logfile format to XML
  • included logging of GUI structure
  • moved robot detection into monitor
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorServlet.java

    r998 r1019  
    1616 
    1717import java.io.BufferedReader; 
     18import java.io.FileNotFoundException; 
    1819import java.io.IOException; 
    1920import java.io.InputStream; 
     
    3738import org.mortbay.jetty.servlet.DefaultServlet; 
    3839 
     40import de.ugoe.cs.util.FileTools; 
    3941import de.ugoe.cs.util.console.Console; 
    4042 
     
    5961     
    6062    /** 
     63     * <p> 
     64     * Name and path of the robot filter. 
     65     * </p> 
     66     */ 
     67    private static final String ROBOTFILTERFILE = "data/robots/robotfilter.txt"; 
     68 
     69    /** 
     70     * <p> 
     71     * Field that contains a regular expression that matches all robots 
     72     * contained in {@link #ROBOTFILTERFILE}. 
     73     * </p> 
     74     */ 
     75    private String robotRegex = null; 
     76 
     77    /** 
    6178     * the message listener to forward received messages to. 
    6279     */ 
     
    7289    HtmlMonitorServlet(HtmlMonitorMessageListener messageListener) { 
    7390        this.messageListener = messageListener; 
     91        try { 
     92            loadRobotRegex(); 
     93        } 
     94        catch (Exception e) { 
     95            Console.println 
     96                ("robot filtering disabled: could not parse robot filter file " + ROBOTFILTERFILE); 
     97        } 
    7498    } 
    7599 
     
    89113                InputStream script = this.getClass().getClassLoader().getResourceAsStream 
    90114                     ("autoquest-htmlmonitor.js"); 
    91              
     115                 
    92116                if (script == null) { 
    93117                    Console.printerrln("could not read autoquest-htmlmonitor.js from classpath"); 
     
    126150        Object value = null; 
    127151        try { 
     152            //InputStream requestInputStream = dumpStreamContent(request.getInputStream()); 
    128153            InputStream requestInputStream = request.getInputStream(); 
    129              
     154 
    130155            value = JSONValue.parseWithException 
    131156                (new InputStreamReader(requestInputStream, "UTF-8")); 
     
    169194                    ("incoming message does not contain valid client infos --> discarding it"); 
    170195            } 
    171             else { 
     196            else if (isRobot(clientInfos.getUserAgent())) { 
     197                Console.printerrln 
     198                    ("ignoring robot " + clientInfos.getUserAgent()); 
     199            } 
     200            else { 
     201                HtmlPageElement guiStructure = extractHtmlPageElements(message, clientInfos); 
    172202                HtmlEvent[] events = extractHtmlEvents(message, clientInfos); 
     203                 
    173204                if (events == null) { 
    174205                    Console.printerrln 
     
    176207                } 
    177208                else { 
    178                     messageListener.handleMessage(clientInfos, events); 
     209                    messageListener.handleMessage(clientInfos, guiStructure, events); 
    179210                } 
    180211            } 
     
    244275            events = new ArrayList<HtmlEvent>(); 
    245276             
     277            HtmlPageElement server = getServerElement(clientInfos); 
     278            HtmlPageElement page = getPageElementRepresentingWebPage(clientInfos, server); 
     279 
    246280            for (int i = 0; i < eventArray.size(); i++) { 
    247281                Object eventObj = eventArray.get(i); 
     
    277311                                (eventType, coordinates, key, scrollPosition, selectedValue)) 
    278312                    { 
    279                         events.add(new HtmlEvent(clientInfos, time, path, eventType, coordinates, 
    280                                                  key, scrollPosition, selectedValue)); 
     313                        path = page.getPath() + path; 
     314                        events.add(new HtmlEvent(clientInfos, time, path, eventType, 
     315                                                 coordinates, key, scrollPosition, selectedValue)); 
    281316                    } 
    282317                    else { 
     
    294329            return null; 
    295330        } 
     331    } 
     332 
     333    /** 
     334     * <p> 
     335     * TODO: comment 
     336     * </p> 
     337     * 
     338     * @param message 
     339     * @param clientInfos 
     340     * @return 
     341     */ 
     342    private HtmlPageElement extractHtmlPageElements(JSONObject      object, 
     343                                                    HtmlClientInfos clientInfos) 
     344    { 
     345        HtmlPageElement server = getServerElement(clientInfos); 
     346        HtmlPageElement page = getPageElementRepresentingWebPage(clientInfos, server); 
     347 
     348        JSONObject jsonPageElement = assertValue(object, "guiModel", JSONObject.class); 
     349        page.addChild(convert(jsonPageElement, page.getPath())); 
     350         
     351        return server; 
     352    } 
     353 
     354    /** 
     355     * <p> 
     356     * TODO: comment 
     357     * </p> 
     358     * 
     359     * @param clientInfos 
     360     * @return 
     361     */ 
     362    private HtmlPageElement getServerElement(HtmlClientInfos clientInfos) { 
     363        String id = clientInfos.getUrl().getHost(); 
     364        if (clientInfos.getUrl().getPort() > -1) { 
     365            id += ":" + clientInfos.getUrl().getPort(); 
     366        } 
     367         
     368        return new HtmlPageElement(null, "server", id, 0); 
     369    } 
     370 
     371    /** 
     372     * <p> 
     373     * TODO: comment 
     374     * </p> 
     375     * 
     376     * @param clientInfos 
     377     */ 
     378    private HtmlPageElement getPageElementRepresentingWebPage(HtmlClientInfos clientInfos, 
     379                                                              HtmlPageElement server) 
     380    { 
     381        String id = clientInfos.getUrl().getPath(); 
     382         
     383        if (clientInfos.getUrl().getQuery() != null) { 
     384            id += "?" + clientInfos.getUrl().getQuery(); 
     385        } 
     386         
     387        HtmlPageElement page = 
     388            new HtmlPageElement(server.getPath(), "document", id, clientInfos.getTitle(), 0); 
     389         
     390        server.addChild(page); 
     391         
     392        return page; 
     393    } 
     394 
     395    /** 
     396     * <p> 
     397     * TODO: comment 
     398     * </p> 
     399     * 
     400     * @param jsonPageElement 
     401     * @return 
     402     */ 
     403    private HtmlPageElement convert(JSONObject jsonPageElement, String parentPath) { 
     404        HtmlPageElement result = null; 
     405 
     406        if (jsonPageElement != null) { 
     407            String tagName = assertValue(jsonPageElement, "tagName", String.class); 
     408            String id = assertValue(jsonPageElement, "id", String.class); 
     409            Integer index = assertValue(jsonPageElement, "index", Integer.class); 
     410 
     411            result = new HtmlPageElement(parentPath, tagName, id, index); 
     412 
     413            JSONArray childElements = assertValue(jsonPageElement, "children", JSONArray.class); 
     414             
     415            if (childElements != null) { 
     416                Object jsonChild; 
     417 
     418                for (int i = 0; i < childElements.size(); i++) { 
     419                    jsonChild = childElements.get(i); 
     420                    if (!(jsonChild instanceof JSONObject)) { 
     421                        Console.printerrln("child " + (i + 1) + " of HTML page element " + tagName + 
     422                                           " is no valid HTML page element"); 
     423                    } 
     424                    else { 
     425                        result.addChild(convert((JSONObject) jsonChild, result.getPath())); 
     426                    } 
     427                } 
     428            } 
     429             
     430        } 
     431         
     432        return result;     
    296433    } 
    297434 
     
    495632    /** 
    496633     * <p> 
     634     * Checks whether an agent is a robot. 
     635     * </p> 
     636     *  
     637     * @param agent 
     638     *            agent that is checked 
     639     * @return true, if the agent is a robot; false otherwise 
     640     */ 
     641    private boolean isRobot(String agent) { 
     642        return agent.matches(robotRegex); 
     643    } 
     644 
     645    /** 
     646     * <p> 
     647     * Reads {@link #ROBOTFILTERFILE} and creates a regular expression that 
     648     * matches all the robots defined in the file. The regular expression is 
     649     * stored in the field {@link #robotRegex}. 
     650     * </p> 
     651     *  
     652     * @throws IOException 
     653     *             thrown if there is a problem reading the robot filter 
     654     * @throws FileNotFoundException 
     655     *             thrown if the robot filter is not found 
     656     */ 
     657    private void loadRobotRegex() throws IOException, FileNotFoundException { 
     658        String[] lines = FileTools.getLinesFromFile(ROBOTFILTERFILE); 
     659        StringBuilder regex = new StringBuilder(); 
     660        for (int i = 0; i < lines.length; i++) { 
     661            regex.append("(.*" + lines[i] + ".*)"); 
     662            if (i != lines.length - 1) { 
     663                regex.append('|'); 
     664            } 
     665        } 
     666        robotRegex = regex.toString(); 
     667    } 
     668 
     669    /** 
     670     * <p> 
    497671     * convenience method for dumping the content of a stream and returning a new stream 
    498672     * containing the same data. 
     
    504678     * @throws IOException if the stream can not be read  
    505679     */ 
    506     /*private InputStream dumpStreamContent(ServletInputStream inputStream) throws IOException { 
     680/*    private InputStream dumpStreamContent(ServletInputStream inputStream) throws IOException { 
    507681        List<Byte> bytes = new ArrayList<Byte>(); 
    508682        int buf; 
Note: See TracChangeset for help on using the changeset viewer.