Ignore:
Timestamp:
02/14/13 15:20:07 (11 years ago)
Author:
pharms
Message:
  • support of new HTML logging format
Location:
trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor
Files:
4 added
6 edited

Legend:

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

    r942 r1069  
    3838 
    3939    /** 
    40      * the path in the HTML DOM to the object on which the event was executed 
    41      */ 
    42     private String path; 
     40     * the HTML element on which the event was executed 
     41     */ 
     42    private HtmlPageElement target; 
     43 
     44    /** 
     45     * the document to which the HTML element on which the event was executed belongs 
     46     */ 
     47    private HtmlDocument targetDocument; 
     48 
     49    /** 
     50     * the targets DOM path through the document to which it belongs 
     51     */ 
     52    private String targetDOMPath; 
    4353 
    4454    /** 
     
    6979    /** 
    7080     * <p> 
    71      * initializes the event with all relevantinfos 
     81     * initializes the event with all relevant infos 
    7282     * </p> 
    7383     * 
    7484     * @param clientInfos    infos about the client that caused the event 
    7585     * @param time           the time stamp of the event 
    76      * @param path           the path in the HTML DOM to the object on which the event was executed 
     86     * @param target         the HTML element on which the event was executed 
    7787     * @param eventType      the type of the event, e.g. onclick 
    7888     * @param coordinates    the coordinates of the event, usually an array with two values 
     
    8696    HtmlEvent(HtmlClientInfos clientInfos, 
    8797              Long            time, 
    88               String          path, 
     98              HtmlPageElement target, 
    8999              String          eventType, 
    90100              Integer[]       coordinates, 
     
    95105        this.clientInfos = clientInfos; 
    96106        this.time = time; 
    97         this.path = path; 
     107        this.target = target; 
     108        this.targetDocument = target.getDocument(); 
     109        this.targetDOMPath = target.getDOMPath(); 
    98110        this.eventType = eventType; 
    99111        this.coordinates = coordinates; 
     
    104116 
    105117    /** 
     118     * <p> 
     119     * initializes the event for which the id of the target is not known yet. In this case 
     120     * the document and DOM path for the target are provided 
     121     * </p> 
     122     * 
     123     * @param clientInfos    infos about the client that caused the event 
     124     * @param time           the time stamp of the event 
     125     * @param targetDocument the document to which the HTML element belongs on which the event was 
     126     *                       executed 
     127     * @param targetDOMPath  the path through the DOM of the document of the HTML element on which 
     128     *                       the event was executed 
     129     * @param eventType      the type of the event, e.g. onclick 
     130     * @param coordinates    the coordinates of the event, usually an array with two values 
     131     *                       (x and y) 
     132     * @param key            if the event is a key event, the key that was pressed or released 
     133     * @param scrollPosition if the event is a scroll event, the resulting position of the 
     134     *                       scrolled element 
     135     * @param selectedValue  if the event is an on change event, the value to which the changed 
     136     *                       element is changed 
     137     */ 
     138    HtmlEvent(HtmlClientInfos clientInfos, 
     139              Long            time, 
     140              HtmlDocument    targetDocument, 
     141              String          targetDOMPath, 
     142              String          eventType, 
     143              Integer[]       coordinates, 
     144              Integer         key, 
     145              Integer[]       scrollPosition, 
     146              String          selectedValue) 
     147    { 
     148        this.clientInfos = clientInfos; 
     149        this.time = time; 
     150        this.targetDocument = targetDocument; 
     151        this.targetDOMPath = targetDOMPath; 
     152        this.eventType = eventType; 
     153        this.coordinates = coordinates; 
     154        this.key = key; 
     155        this.scrollPosition = scrollPosition; 
     156        this.selectedValue = selectedValue; 
     157    } 
     158 
     159    /** 
    106160     * @return the clientInfos 
    107161     */ 
     
    118172 
    119173    /** 
    120      * @return the path 
    121      */ 
    122     String getPath() { 
    123         return path; 
     174     * @return the target 
     175     */ 
     176    HtmlPageElement getTarget() { 
     177        return target; 
     178    } 
     179 
     180    /** 
     181     * @return the targetDocument 
     182     */ 
     183    HtmlDocument getTargetDocument() { 
     184        return targetDocument; 
     185    } 
     186 
     187    /** 
     188     * @return the targetDOMPath 
     189     */ 
     190    String getTargetDOMPath() { 
     191        return targetDOMPath; 
    124192    } 
    125193 
  • trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorLogManager.java

    r1019 r1069  
    116116    @Override 
    117117    public void handleMessage(HtmlClientInfos clientInfos, 
    118                               HtmlPageElement guiStructure, 
     118                              HtmlGUIElement guiStructure, 
    119119                              HtmlEvent[]     events) 
    120120    { 
     
    140140            Console.printerrln("could not handle message of client " + clientInfos.getClientId() + 
    141141                               ": " + e); 
     142            e.printStackTrace(); 
    142143            Console.logException(e); 
    143144             
  • trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorMessageListener.java

    r1022 r1069  
    3636     */ 
    3737    void handleMessage(HtmlClientInfos clientInfos, 
    38                        HtmlPageElement guiStructure, 
     38                       HtmlGUIElement guiStructure, 
    3939                       HtmlEvent[]     events); 
    4040 
  • trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorOutputWriter.java

    r1022 r1069  
    179179    @Override 
    180180    public void handleMessage(HtmlClientInfos clientInfos, 
    181                               HtmlPageElement guiStructure, 
     181                              HtmlGUIElement guiStructure, 
    182182                              HtmlEvent[]     events) 
    183183    { 
     
    214214     * @param guiStructure the GUI structure to be logged 
    215215     */ 
    216     private void dumpGuiStructure(HtmlPageElement guiStructure) { 
    217         outputWriter.print("<component path=\""); 
    218         outputWriter.print(guiStructure.getPath()); 
     216    private void dumpGuiStructure(HtmlGUIElement guiStructure) { 
     217        outputWriter.print("<component id=\""); 
     218        outputWriter.print(guiStructure.getId()); 
    219219        outputWriter.println("\">"); 
    220220         
    221         dumpParam("class", guiStructure.getTagName()); 
    222         dumpParam("htmlId", guiStructure.getId()); 
    223         dumpParam("title", guiStructure.getTitle()); 
    224         dumpParam("index", guiStructure.getIndex()); 
    225         dumpParam("parent", guiStructure.getParentPath()); 
     221        if (guiStructure instanceof HtmlServer) { 
     222            dumpParam("host", ((HtmlServer) guiStructure).getName()); 
     223            dumpParam("port", ((HtmlServer) guiStructure).getPort()); 
     224        } 
     225        else if (guiStructure instanceof HtmlDocument) { 
     226            dumpParam("path", ((HtmlDocument) guiStructure).getPath()); 
     227            dumpParam("query", ((HtmlDocument) guiStructure).getQuery()); 
     228            dumpParam("title", ((HtmlDocument) guiStructure).getTitle()); 
     229        } 
     230        else if (guiStructure instanceof HtmlPageElement) { 
     231            dumpParam("tagname", ((HtmlPageElement) guiStructure).getTagName()); 
     232            dumpParam("htmlid", ((HtmlPageElement) guiStructure).getHtmlId()); 
     233            dumpParam("index", ((HtmlPageElement) guiStructure).getIndex()); 
     234        } 
     235         
     236        dumpParam("parent", guiStructure.getParentId()); 
    226237         
    227238        outputWriter.println("</component>"); 
    228239         
    229240        if (guiStructure.getChildren() != null) { 
    230             for (HtmlPageElement child : guiStructure.getChildren()) { 
     241            for (HtmlGUIElement child : guiStructure.getChildren()) { 
    231242                dumpGuiStructure(child); 
    232243            } 
     
    260271 
    261272        dumpParam("selectedValue", event.getSelectedValue()); 
    262         dumpParam("target", event.getPath()); 
     273         
     274        if (event.getTarget() != null) { 
     275            dumpParam("target", event.getTarget().getId()); 
     276        } 
     277        else { 
     278            dumpParam("targetDocument", event.getTargetDocument().getId()); 
     279            dumpParam("targetDOMPath", event.getTargetDOMPath()); 
     280        } 
    263281        dumpParam("timestamp", event.getTime()); 
    264282         
  • trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorServlet.java

    r1022 r1069  
    7878     * the message listener to forward received messages to. 
    7979     */ 
     80    private HtmlGUIElementManager guiElementManager = new HtmlGUIElementManager(); 
     81 
     82    /** 
     83     * the message listener to forward received messages to. 
     84     */ 
    8085    private transient HtmlMonitorMessageListener messageListener; 
    8186 
     
    199204            } 
    200205            else { 
    201                 HtmlPageElement guiStructure = extractHtmlPageElements(message, clientInfos); 
     206                HtmlGUIElement guiStructure = extractHtmlPageElements(message, clientInfos); 
    202207                HtmlEvent[] events = extractHtmlEvents(message, clientInfos); 
    203208                 
     
    275280            events = new ArrayList<HtmlEvent>(); 
    276281             
    277             HtmlPageElement server = getServerElement(clientInfos); 
    278             HtmlPageElement page = getPageElementRepresentingWebPage(clientInfos, server); 
     282            HtmlServer server = getServerElement(clientInfos); 
     283            HtmlDocument document = getPageElementRepresentingWebPage(clientInfos, server); 
    279284 
    280285            for (int i = 0; i < eventArray.size(); i++) { 
     
    285290                else { 
    286291                    Long time = assertValue(((JSONObject) eventObj), "time", Long.class); 
    287                     String path = assertValue(((JSONObject) eventObj), "path", String.class); 
     292                    String domPath = assertValue(((JSONObject) eventObj), "path", String.class); 
    288293                    String eventType = 
    289294                        assertValue(((JSONObject) eventObj), "eventType", String.class); 
     
    302307                        Console.printerrln(eventType + " event has no valid timestamp"); 
    303308                    } 
    304                     else if (path == null) { 
    305                         Console.printerrln(eventType + " event has no valid path"); 
     309                    else if (domPath == null) { 
     310                        Console.printerrln(eventType + " event has no valid DOM path"); 
    306311                    } 
    307312                    else if ((coordinates != null) && (coordinates.length != 2)) { 
     
    311316                                (eventType, coordinates, key, scrollPosition, selectedValue)) 
    312317                    { 
    313                         path = page.getPath() + path; 
    314                         events.add(new HtmlEvent(clientInfos, time, path, eventType, 
    315                                                  coordinates, key, scrollPosition, selectedValue)); 
     318                        HtmlPageElement target = 
     319                            guiElementManager.getPageElement(document, domPath); 
     320                         
     321                        if (target != null) { 
     322                            events.add(new HtmlEvent(clientInfos, time, target, eventType, 
     323                                                     coordinates, key, scrollPosition, 
     324                                                     selectedValue)); 
     325                        } 
     326                        else { 
     327                            events.add(new HtmlEvent(clientInfos, time, document, domPath, 
     328                                                     eventType, coordinates, key, scrollPosition, 
     329                                                     selectedValue)); 
     330                        } 
    316331                    } 
    317332                    else { 
     
    342357     *         representation of the server of the HTML page that was observed  
    343358     */ 
    344     private HtmlPageElement extractHtmlPageElements(JSONObject      object, 
    345                                                     HtmlClientInfos clientInfos) 
     359    private HtmlServer extractHtmlPageElements(JSONObject      object, 
     360                                               HtmlClientInfos clientInfos) 
    346361    { 
    347         HtmlPageElement server = getServerElement(clientInfos); 
    348         HtmlPageElement page = getPageElementRepresentingWebPage(clientInfos, server); 
     362        HtmlServer server = getServerElement(clientInfos); 
     363        HtmlDocument document = getPageElementRepresentingWebPage(clientInfos, server); 
    349364 
    350365        JSONObject jsonPageElement = assertValue(object, "guiModel", JSONObject.class); 
    351         page.addChild(convert(jsonPageElement, page.getPath())); 
     366        document.addChild(convert(jsonPageElement, document, null)); 
    352367         
    353368        return server; 
     
    364379     * @return as described 
    365380     */ 
    366     private HtmlPageElement getServerElement(HtmlClientInfos clientInfos) { 
    367         String id = clientInfos.getUrl().getHost(); 
     381    private HtmlServer getServerElement(HtmlClientInfos clientInfos) { 
     382        String host = clientInfos.getUrl().getHost(); 
     383        int port = 80; 
     384         
    368385        if (clientInfos.getUrl().getPort() > -1) { 
    369             id += ":" + clientInfos.getUrl().getPort(); 
    370         } 
    371          
    372         return new HtmlPageElement(null, "server", id, 0); 
     386            port = clientInfos.getUrl().getPort(); 
     387        } 
     388         
     389        return guiElementManager.createHtmlServer(host, port); 
    373390    } 
    374391 
     
    384401     * @return as described 
    385402     */ 
    386     private HtmlPageElement getPageElementRepresentingWebPage(HtmlClientInfos clientInfos, 
    387                                                               HtmlPageElement server) 
     403    private HtmlDocument getPageElementRepresentingWebPage(HtmlClientInfos clientInfos, 
     404                                                           HtmlServer      server) 
    388405    { 
    389         String id = clientInfos.getUrl().getPath(); 
     406        String path = clientInfos.getUrl().getPath(); 
     407        String query = null; 
    390408         
    391409        if (clientInfos.getUrl().getQuery() != null) { 
    392             id += "?" + clientInfos.getUrl().getQuery(); 
    393         } 
    394          
    395         HtmlPageElement page = 
    396             new HtmlPageElement(server.getPath(), "document", id, clientInfos.getTitle(), 0); 
    397          
    398         server.addChild(page); 
    399          
    400         return page; 
     410            query = "?" + clientInfos.getUrl().getQuery(); 
     411        } 
     412         
     413        HtmlDocument document = guiElementManager.createHtmlDocument 
     414            (server, path, query, clientInfos.getTitle()); 
     415         
     416        server.addChild(document); 
     417         
     418        return document; 
    401419    } 
    402420 
     
    408426     * 
    409427     * @param jsonPageElement the JSON object to be converted 
    410      * @param parentPath      the path through the DOM of the parent HTML page element of the 
    411      *                        converted one 
     428     * @param document        the document to which the page element belongs 
     429     * @param parent          the parent page element of the converted element, of null, if none 
     430     *                        is present. In this case the document is considered the parent 
     431     *                        element. 
    412432     *                         
    413433     * @return as described. 
    414434     */ 
    415     private HtmlPageElement convert(JSONObject jsonPageElement, String parentPath) { 
     435    private HtmlPageElement convert(JSONObject      jsonPageElement, 
     436                                    HtmlDocument    document, 
     437                                    HtmlPageElement parent) 
     438    { 
    416439        HtmlPageElement result = null; 
    417440 
    418441        if (jsonPageElement != null) { 
    419442            String tagName = assertValue(jsonPageElement, "tagName", String.class); 
    420             String id = assertValue(jsonPageElement, "id", String.class); 
     443            String htmlid = assertValue(jsonPageElement, "htmlId", String.class); 
    421444            Integer index = assertValue(jsonPageElement, "index", Integer.class); 
    422445 
    423             result = new HtmlPageElement(parentPath, tagName, id, index); 
     446            result = guiElementManager.createHtmlPageElement 
     447                (document, parent, tagName, htmlid, index); 
    424448 
    425449            JSONArray childElements = assertValue(jsonPageElement, "children", JSONArray.class); 
     
    435459                    } 
    436460                    else { 
    437                         result.addChild(convert((JSONObject) jsonChild, result.getPath())); 
     461                        result.addChild(convert((JSONObject) jsonChild, document, result)); 
    438462                    } 
    439463                } 
  • trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlPageElement.java

    r1022 r1069  
    1515package de.ugoe.cs.autoquest.htmlmonitor; 
    1616 
    17 import java.util.ArrayList; 
    18 import java.util.List; 
    19  
    2017/** 
    2118 * <p> 
    22  * represents an element of an HTML GUI. This can be a server, which is usually the root of a 
    23  * GUI structure, a web page, or a tag within a web page. 
     19 * represents an element of an HTML GUI, i.e. a tag within a web page. 
    2420 * </p> 
    2521 *  
    2622 * @author Patrick Harms 
    2723 */ 
    28 class HtmlPageElement { 
    29  
    30     /** 
    31      * path to the parent of this page element or null, if this is the root element 
    32      */ 
    33     private String parentPath; 
    34      
    35     /** 
    36      * the name of the tag represented by this page element. May also be the name of the server 
    37      * or the page. 
     24class HtmlPageElement extends HtmlGUIElement { 
     25 
     26    /** 
     27     * the document to which the represented tag belongs 
     28     */ 
     29    private HtmlDocument document; 
     30     
     31    /** 
     32     * the parent page element; if null, the document is considered the parent 
     33     */ 
     34    private HtmlPageElement parent; 
     35     
     36    /** 
     37     * the name of the tag represented by this page element. 
    3838     */ 
    3939    private String tagName; 
    4040     
    4141    /** 
    42      * the id of the page element. May also be the name of the server including port number or the 
    43      * URL of the page 
    44      */ 
    45     private String id; 
    46      
    47     /** 
    48      * the title of the page if a page is represented through this element 
    49      */ 
    50     private String title; 
     42     * the id of the page element inside the DOM. 
     43     */ 
     44    private String htmlId; 
    5145     
    5246    /** 
     
    5751     
    5852    /** 
    59      * the children of this element 
    60      */ 
    61     private List<HtmlPageElement> children; 
    62  
    63     /** 
    6453     * <p> 
    6554     * instantiates a new element representing a tag in an HTML page 
    6655     * </p> 
    6756     * 
    68      * @param parentPath the path through the DOM to the parent node of the represented tag  
    69      * @param tagName    the name of the represented tag 
    70      * @param id         the id of the tag in the DOM 
    71      * @param index      the index of the represented tag regarding all tags with the same tag name 
    72      *                   in the list of children of the parent tag 
    73      */ 
    74     HtmlPageElement(String parentPath, String tagName, String id, Integer index) { 
    75         this.parentPath = parentPath; 
     57     * @param id       the id of the page element 
     58     * @param document the document to which the represented tag belongs 
     59     * @param parent   the parent page element; if null, the document is considered the parent 
     60     * @param tagName  the name of the represented tag 
     61     * @param htmlId   the id of the tag in the DOM 
     62     * @param index    the index of the represented tag regarding all tags with the same 
     63     *                 tag name in the list of children of the parent tag 
     64     */ 
     65    HtmlPageElement(String          id, 
     66                    HtmlDocument    document, 
     67                    HtmlPageElement parent, 
     68                    String          tagName, 
     69                    String          htmlId, 
     70                    Integer         index) 
     71    { 
     72        super(id, parent == null ? document : parent); 
     73         
     74        if (document == null) { 
     75            throw new IllegalArgumentException("document must not be null"); 
     76        } 
     77 
     78        if (tagName == null) { 
     79            throw new IllegalArgumentException("tagName must not be null"); 
     80        } 
     81         
     82        if ((htmlId == null) && (index == null)) { 
     83            throw new IllegalArgumentException("either one of htmlId and index must not be null"); 
     84        } 
     85         
     86        this.document = document; 
     87        this.parent = parent; 
    7688        this.tagName = tagName; 
    77         this.id = id; 
     89        this.htmlId = htmlId; 
    7890        this.index = index; 
    7991    } 
     
    8193    /** 
    8294     * <p> 
    83      * instantiates a new element representing an HTML page 
     95     * returns the document to which the represented tag belongs 
    8496     * </p> 
    8597     * 
    86      * @param parentPath the path through the DOM to the parent node of the represented tag which is 
    87      *                   usually a server 
    88      * @param tagName    the name of the represented tag which is the path of the web page 
    89      * @param title      the title of the web page 
    90      * @param id         the id of the web page which is its path 
    91      * @param index      usually 0 
    92      */ 
    93     HtmlPageElement(String parentPath, String tagName, String id, String title, Integer index) { 
    94         this(parentPath, tagName, id, index); 
    95         this.title = title; 
    96     } 
    97  
    98     /** 
    99      * <p> 
    100      * returns the name of the tag represented by this page element. May also be the name of the 
    101      * server or the page. 
     98     * @return the document 
     99     */ 
     100    HtmlDocument getDocument() { 
     101        return document; 
     102    } 
     103 
     104    /** 
     105     * <p> 
     106     * returns the name of the tag represented by this page element. 
    102107     * </p> 
    103108     *  
     
    110115    /** 
    111116     * <p> 
    112      * returns the id of the page element. May also be the name of the server including port 
    113      * number or the URL of the page 
     117     * returns the id of the page element. 
    114118     * </p> 
    115119     *  
    116120     * @return the id 
    117121     */ 
    118     String getId() { 
    119         return id; 
    120     } 
    121  
    122     /** 
    123      * <p> 
    124      * returns the title of the page if a page is represented through this element 
    125      * </p> 
    126      *  
    127      * @return the title 
    128      */ 
    129     String getTitle() { 
    130         return title; 
     122    String getHtmlId() { 
     123        return htmlId; 
    131124    } 
    132125 
     
    141134    Integer getIndex() { 
    142135        return index; 
    143     } 
    144  
    145     /** 
    146      * <p> 
    147      * returns the children of this element if any, null else 
    148      * </p> 
    149      *  
    150      * @return the children 
    151      */ 
    152     List<HtmlPageElement> getChildren() { 
    153         return children; 
    154     } 
    155  
    156  
    157     /** 
    158      * adds a child to this element 
    159      *  
    160      * @param child the child to be added 
    161      */ 
    162     void addChild(HtmlPageElement child) { 
    163         if (child != null) { 
    164             if (children == null) { 
    165                 children = new ArrayList<HtmlPageElement>(); 
    166             } 
    167              
    168             children.add(child); 
    169         } 
    170     } 
    171  
    172     /** 
    173      * <p> 
    174      * returns the path to the parent of this page element or null, if this is the root element 
    175      * </p> 
    176      * 
    177      * @return as described 
    178      */ 
    179     String getParentPath() { 
    180         return parentPath; 
    181136    } 
    182137 
     
    190145     * @return as described 
    191146     */ 
    192     String getPath() { 
     147    String getDOMPath() { 
    193148        StringBuffer result = new StringBuffer(); 
    194         if (parentPath != null) { 
    195             result.append(parentPath); 
     149        if (parent != null) { 
     150            result.append(parent.getDOMPath()); 
    196151        } 
    197152 
     
    199154        result.append(tagName); 
    200155         
    201         if ((id != null) && (!"".equals(id))) { 
    202             result.append("(id="); 
    203             result.append(id); 
     156        if ((htmlId != null) && (!"".equals(htmlId))) { 
     157            result.append("(htmlId="); 
     158            result.append(htmlId); 
    204159            result.append(")"); 
    205160        } 
     
    213168    } 
    214169 
     170    /* (non-Javadoc) 
     171     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlGUIElement#equals(de.ugoe.cs.autoquest.htmlmonitor.HtmlGUIElement) 
     172     */ 
     173    @Override 
     174    public boolean equals(HtmlGUIElement obj) { 
     175        if (this == obj) { 
     176            return true; 
     177        } 
     178        else if (obj instanceof HtmlPageElement) { 
     179            return equals((HtmlPageElement) obj); 
     180        } 
     181        else { 
     182            return false; 
     183        } 
     184    } 
     185 
     186    /* (non-Javadoc) 
     187     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlGUIElement#equals(de.ugoe.cs.autoquest.htmlmonitor.HtmlGUIElement) 
     188     */ 
     189    public boolean equals(HtmlPageElement other) { 
     190        if (this == other) { 
     191            return true; 
     192        } 
     193 
     194        return (document.equals(other.document) && tagName.equals(other.tagName) && 
     195                (parent != null ? parent.equals(other.parent) : other.parent == null) && 
     196                (htmlId != null ? htmlId.equals(other.htmlId) : other.htmlId == null) && 
     197                (index != null ? index.equals(other.index) : other.index == null)); 
     198    } 
     199 
     200    /* (non-Javadoc) 
     201     * @see java.lang.Object#hashCode() 
     202     */ 
     203    @Override 
     204    public int hashCode() { 
     205        return document.hashCode() + tagName.hashCode() + (parent != null ? parent.hashCode() : 0) + 
     206            (htmlId != null ? htmlId.hashCode() : 0) + (index != null ? index : 0); 
     207    } 
     208 
    215209} 
Note: See TracChangeset for help on using the changeset viewer.