Changeset 1856


Ignore:
Timestamp:
01/07/15 14:04:59 (9 years ago)
Author:
dmay
Message:

a big wave of refactorings/documentation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-plugin-jfc/src/main/java/de/ugoe/cs/autoquest/plugin/jfc/commands/CMDgenerateJacaretoReplay.java

    r1838 r1856  
    5050import de.ugoe.cs.util.console.GlobalDataContainer; 
    5151 
    52 // helper class for the tree like structure part within a Jacareto file 
    53 class StructureNode { 
    54     public static int nextRef = 0; 
    55  
    56     public String content; 
    57     public ArrayList<StructureNode> children; 
    58  
    59     public StructureNode(String type) { 
    60         setContent(type); 
    61         children = new ArrayList<StructureNode>(); 
    62     } 
    63  
    64     public StructureNode() { 
    65         content = "<Recordable ref=\"" + (nextRef++) + "\" />"; 
    66         children = new ArrayList<StructureNode>(); 
    67     } 
    68  
    69     public void setContent(String type) { 
    70         content = "<StructureElement class=\"jacareto.struct." + type + "\">"; 
    71     } 
    72  
    73     public StructureNode add(String type) { 
    74         StructureNode node = new StructureNode(type); 
    75         children.add(node); 
    76         return node; 
    77     } 
    78  
    79     public void addRecordable() { 
    80         children.add(new StructureNode()); 
    81     } 
    82  
    83     @Override 
    84     public String toString() { 
    85         String separator = System.getProperty("line.separator"); 
    86         String result = content + separator; 
    87  
    88         for (StructureNode child : children) { 
    89             result += child.toString(); 
    90         } 
    91  
    92         if (content.endsWith("/>")) { 
    93             return result; 
    94         } 
    95         return result + "</StructureElement>" + separator; 
    96     } 
    97 } 
    98  
    9952/** 
    10053 * <p> 
     
    10659 */ 
    10760public class CMDgenerateJacaretoReplay implements Command { 
     61 
     62    /** 
     63     * <p> 
     64     * Helper class for the tree like structure part within a Jacareto file. 
     65     * </p> 
     66     */ 
     67    private static class StructureNode { 
     68 
     69        /** 
     70         * <p> 
     71         * Keeps track of the next structure node id. 
     72         * </p> 
     73         */ 
     74        public static int nextRef = 0; 
     75 
     76        /** 
     77         * <p> 
     78         * The node's type packaged into an XML string. 
     79         * </p> 
     80         */ 
     81        public String content; 
     82 
     83        /** 
     84         * <p> 
     85         * This node's children. 
     86         * </p> 
     87         */ 
     88        public ArrayList<StructureNode> children; 
     89 
     90        /** 
     91         * <p> 
     92         * Constructor. Creates a new StructureNode of a specified type and builds its Jacareto XML 
     93         * representation. 
     94         * </p> 
     95         *  
     96         * @param type 
     97         *            the type of this StructureNode, for example: 'MouseDownEvent' 
     98         */ 
     99        public StructureNode(String type) { 
     100            setContent(type); 
     101            children = new ArrayList<StructureNode>(); 
     102        } 
     103 
     104        /** 
     105         * <p> 
     106         * Constructor. Creates a StructureNode of type 'Recordable' with a valid id and builds its 
     107         * Jacareto XML representation. 
     108         * </p> 
     109         */ 
     110        public StructureNode() { 
     111            content = "<Recordable ref=\"" + (nextRef++) + "\" />"; 
     112            children = new ArrayList<StructureNode>(); 
     113        } 
     114 
     115        /** 
     116         * <p> 
     117         * Builds the XML representation of a Jacareto structure type. 
     118         * </p> 
     119         *  
     120         * @param type 
     121         *            the type of this StructureNode, for example: 'MouseDownEvent' 
     122         */ 
     123        public void setContent(String type) { 
     124            content = "<StructureElement class=\"jacareto.struct." + type + "\">"; 
     125        } 
     126 
     127        /** 
     128         * <p> 
     129         * Adds a new StructureNode as a child of this node. 
     130         * </p> 
     131         *  
     132         * @param type 
     133         *            the type of the child node, for example: 'MouseDownEvent' 
     134         */ 
     135        public StructureNode add(String type) { 
     136            StructureNode node = new StructureNode(type); 
     137            children.add(node); 
     138            return node; 
     139        } 
     140 
     141        /** 
     142         * <p> 
     143         * Builds the XML representation of a Jacareto structure type. 
     144         * </p> 
     145         *  
     146         * @param type 
     147         *            the type of this StructureNode, for example: 'MouseDownEvent' 
     148         */ 
     149        public void addRecordable() { 
     150            children.add(new StructureNode()); 
     151        } 
     152 
     153        /** 
     154         * <p> 
     155         * Returns a Jacareto XML representation of this StructureNode, includin all its children. 
     156         * </p> 
     157         */ 
     158        @Override 
     159        public String toString() { 
     160            String separator = System.getProperty("line.separator"); 
     161            String result = content + separator; 
     162 
     163            for (StructureNode child : children) { 
     164                result += child.toString(); 
     165            } 
     166 
     167            if (content.endsWith("/>")) { 
     168                return result; 
     169            } 
     170            return result + "</StructureElement>" + separator; 
     171        } 
     172    } 
     173 
     174    /** 
     175     * <p> 
     176     * The time it takes for Jacareto to replay an event in ms. 
     177     * </p> 
     178     */ 
    108179    private static final int EVENT_DURATION = 150; 
     180 
     181    /** 
     182     * <p> 
     183     * The time it takes for Jacareto to replay each part of a double click event in ms. 
     184     * </p> 
     185     */ 
    109186    private static final int DOUBLE_CLICK_DURATION = 50; 
     187 
     188    /** 
     189     * <p> 
     190     * Application startup time in ms. The application needs to be fully initialized before Jacareto 
     191     * can start replaying. 
     192     * </p> 
     193     */ 
    110194    private static final int STARTUP_DELAY = 10000; 
    111195 
     196    /** 
     197     * <p> 
     198     * The GUI element which is currently focused. 
     199     * </p> 
     200     */ 
    112201    private JFCGUIElement currentFocus; 
     202 
     203    /** 
     204     * <p> 
     205     * A tree of StructureNodes which represents the structure part inside a Jacareto XML file. 
     206     * </p> 
     207     */ 
    113208    private StructureNode structure; 
    114209 
     210    /** 
     211     * <p> 
     212     * XML structure for key events modeled as StructureNodes. 
     213     * </p> 
     214     */ 
    115215    private StructureNode lastKeySequenceEvent; 
     216 
     217    /** 
     218     * <p> 
     219     * XML structure for key events modeled as StructureNodes. 
     220     * </p> 
     221     */ 
    116222    private StructureNode lastKeyTypedEvent; 
     223 
     224    /** 
     225     * <p> 
     226     * Bitmask which represents currently used key modifiers (such as shift etc). 
     227     * </p> 
     228     */ 
    117229    private int currentKeyModifiers; 
    118230 
     231    /** 
     232     * <p> 
     233     * Maps VirtualKey objects for modifier keys back to AWT Event codes. 
     234     * </p> 
     235     */ 
    119236    private HashMap<VirtualKey, Integer> modifiers; 
    120237 
     238    /** 
     239     * <p> 
     240     * XML structure for mouse events modeled as StructureNodes. 
     241     * </p> 
     242     */ 
    121243    private StructureNode lastMouseClickEvent; 
     244 
     245    /** 
     246     * <p> 
     247     * XML structure for focus events modeled as StructureNodes. 
     248     * </p> 
     249     */ 
    122250    private StructureNode lastFocusChangeEvent; 
     251 
     252    /** 
     253     * <p> 
     254     * XML structure for item and action events modeled as StructureNodes. 
     255     * </p> 
     256     */ 
    123257    private StructureNode lastItemActionEvent; 
     258 
     259    /** 
     260     * <p> 
     261     * The target of the last mouseDownEvent. It is necessary to save this because mouse down and up 
     262     * targets can differ. 
     263     * </p> 
     264     */ 
    124265    private IEventTarget lastMouseDownTarget; 
     266 
     267    /** 
     268     * <p> 
     269     * Associates the name of a menu element with its corresponding JFCGUIElement. 
     270     * </p> 
     271     */ 
    125272    private HashMap<String, JFCGUIElement> menuElements; 
     273 
     274    /** 
     275     * <p> 
     276     * The menu hierarchy. 
     277     * </p> 
     278     */ 
    126279    private List<String> menuList; 
    127280 
     
    184337 
    185338        sequences = (Collection<List<Event>>) dataObject; 
    186  
    187339        menuElements = new HashMap<>(); 
    188  
    189         // map which maps VirtualKeys back to awt key modifier codes 
    190         modifiers = new HashMap<>(); 
    191         modifiers.put(VirtualKey.SHIFT, 1); 
    192         modifiers.put(VirtualKey.CONTROL, 2); 
    193         modifiers.put(VirtualKey.ALT, 8); 
    194         modifiers.put(VirtualKey.ALT_GRAPH, 32); 
     340        modifiers = createModifierMap(); 
    195341        currentKeyModifiers = 0; 
    196  
    197342        StructureNode.nextRef = 0; 
    198343 
     
    200345    } 
    201346 
     347    /** 
     348     * <p> 
     349     * Associates keyboard modifier keys with their AWT event codes. 
     350     * </p> 
     351     */ 
     352    private HashMap<VirtualKey, Integer> createModifierMap() { 
     353        HashMap<VirtualKey, Integer> result = new HashMap<>(); 
     354 
     355        result.put(VirtualKey.SHIFT, 1); 
     356        result.put(VirtualKey.CONTROL, 2); 
     357        result.put(VirtualKey.ALT, 8); 
     358        result.put(VirtualKey.ALT_GRAPH, 32); 
     359 
     360        return result; 
     361    } 
     362 
     363    /** 
     364     * <p> 
     365     * Writes a line and creates a new line. 
     366     * </p> 
     367     *  
     368     * @param writer 
     369     *            the BufferedWriter which writes the XML 
     370     * @param line 
     371     *            the line to write 
     372     *  
     373     */ 
    202374    private void writeLine(BufferedWriter writer, String line) throws IOException { 
    203375        writer.write(line); 
     
    205377    } 
    206378 
     379    /** 
     380     * <p> 
     381     * Writes the Jacareto XML head part. This mainly contains information about the state of the 
     382     * system when the replay was captured. 
     383     *  
     384     * @param writer 
     385     *            the BufferedWriter which writes the XML 
     386     * @param classname 
     387     *            name of the main class of the program that will be replayed 
     388     * @param basepath 
     389     *            a basepath that is prepended to all paths specified in classpathext 
     390     * @param classpathext 
     391     *            additional required resources (e.g. jar files) 
     392     *  
     393     *            </p> 
     394     */ 
    207395    private void writeJacaretoHead(BufferedWriter writer, 
    208396                                   String classname, 
     
    251439    } 
    252440 
     441    /** 
     442     * <p> 
     443     * Writes Jacareto XML code for all events within the Autoquest sequences. 
     444     * </p> 
     445     *  
     446     * @param writer 
     447     *            the BufferedWriter which writes the XML 
     448     * @param sequences 
     449     *            the Autoquest sequences 
     450     *  
     451     */ 
    253452    private void writeJacaretoEvents(BufferedWriter writer, Collection<List<Event>> sequences) 
    254453        throws IOException 
     
    267466 
    268467                if (event.getType() instanceof MouseButtonDown) { 
    269                     handleMouseDown(writer, event, "MouseClick"); 
     468                    handleMouseButtonDown(writer, event); 
    270469                } 
    271470                else if (event.getType() instanceof MouseButtonUp) { 
    272                     handleMouseUp(writer, event); 
     471                    handleMouseButtonUp(writer, event); 
    273472                } 
    274473                else if (event.getType() instanceof MouseDoubleClick) { 
    275                     StructureNode multiClick = structure.add("MultipleMouseClick"); 
    276  
    277                     // first click 
    278                     lastMouseClickEvent = multiClick.add("MouseClick"); 
    279                     writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
    280                                          DOUBLE_CLICK_DURATION, 501); 
    281                     writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
    282                                          DOUBLE_CLICK_DURATION, 502); 
    283                     writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
    284                                          DOUBLE_CLICK_DURATION, 500); 
    285                     // second click 
    286                     lastMouseClickEvent = multiClick.add("MouseClick"); 
    287                     writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
    288                                          DOUBLE_CLICK_DURATION, 501); 
    289                     writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
    290                                          DOUBLE_CLICK_DURATION, 502); 
    291                     writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
    292                                          DOUBLE_CLICK_DURATION, 500); 
    293  
    294                     lastMouseClickEvent = null; 
     474                    handleMouseDoubleClick(writer, event); 
    295475                } 
    296476                else if (event.getType() instanceof MouseClick) { 
     
    315495                    } 
    316496 
    317                     lastKeySequenceEvent = null; 
    318  
    319                     if (lastMouseClickEvent != null) { 
    320                         if (lastMouseDownTarget == event.getTarget()) { 
    321                             // this is the standard case: 
    322                             // mouseDown, mouseUp and mouseClick sequence 
    323                             // was triggered on this target 
    324  
    325                             writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
    326                                                  EVENT_DURATION, 500); 
    327                             writeItemActionEvent(writer, event); 
    328  
    329                             if (lastFocusChangeEvent == null) { 
    330                                 // write structure sequentially 
    331                                 structure.children.add(lastMouseClickEvent); 
    332                                 structure.children.add(lastItemActionEvent); 
    333                             } 
    334                             else { 
    335                                 // with nested structure 
    336                                 structure.children.add(lastItemActionEvent); 
    337                                 lastItemActionEvent.children.add(0, lastFocusChangeEvent); 
    338                                 lastFocusChangeEvent.children.add(0, lastMouseClickEvent); 
    339  
    340                                 lastFocusChangeEvent = null; 
    341                                 lastMouseClickEvent = null; 
    342                             } 
    343                         } 
    344                         else { 
    345                             // target of mouseDown and mouseClick are different 
    346                             // -> this is, for example, a click on a menu item 
    347                             // within a condensed sequence 
    348                             commitFocusEvent(); 
    349  
    350                             // finish the last click on the old target 
    351                             writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
    352                                                  EVENT_DURATION, 500); 
    353                             structure.children.add(lastMouseClickEvent); 
    354  
    355                             // and generate a new one 
    356                             generateFullClick(writer, event, (JFCGUIElement) event.getTarget()); 
    357                         } 
    358                     } 
    359                     else { 
    360                         // a target was clicked repeatedly: 
    361                         // the condensed sequence contains no mouseDowns or 
    362                         // mouseUps anymore 
    363                         // -> just generate another full click 
    364                         generateFullClick(writer, event, (JFCGUIElement) event.getTarget()); 
    365                     } 
     497                    handleMouseClick(writer, event); 
    366498                } 
    367499                else if (event.getType() instanceof KeyboardFocusChange) { 
    368                     lastKeySequenceEvent = null; 
    369  
    370                     writeFocusChangeEvent(writer, event); 
     500                    handleKeyboardFocusChange(writer, event); 
    371501                } 
    372502                else if (event.getType() instanceof MouseDragAndDrop) { 
     
    390520    } 
    391521 
    392     private void handleMouseDown(BufferedWriter writer, Event event, String structureName) 
    393         throws IOException 
    394     { 
     522    // EVENT HANDLERS 
     523 
     524    private void handleMouseClick(BufferedWriter writer, Event event) throws IOException { 
     525        lastKeySequenceEvent = null; 
     526 
     527        if (lastMouseClickEvent != null) { 
     528            if (lastMouseDownTarget == event.getTarget()) { 
     529                // this is the standard case: 
     530                // mouseDown, mouseUp and mouseClick sequence 
     531                // was triggered on this target 
     532 
     533                writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
     534                                     EVENT_DURATION, 500); 
     535                writeItemActionEvent(writer, event); 
     536 
     537                if (lastFocusChangeEvent == null) { 
     538                    // write structure sequentially 
     539                    structure.children.add(lastMouseClickEvent); 
     540                    structure.children.add(lastItemActionEvent); 
     541                } 
     542                else { 
     543                    // with nested structure 
     544                    structure.children.add(lastItemActionEvent); 
     545                    lastItemActionEvent.children.add(0, lastFocusChangeEvent); 
     546                    lastFocusChangeEvent.children.add(0, lastMouseClickEvent); 
     547 
     548                    lastFocusChangeEvent = null; 
     549                    lastMouseClickEvent = null; 
     550                } 
     551            } 
     552            else { 
     553                // target of mouseDown and mouseClick are different 
     554                // -> this is, for example, a click on a menu item 
     555                // within a condensed sequence 
     556                commitFocusEvent(); 
     557 
     558                // finish the last click on the old target 
     559                writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
     560                                     EVENT_DURATION, 500); 
     561                structure.children.add(lastMouseClickEvent); 
     562 
     563                // and generate a new one 
     564                generateFullClick(writer, event, (JFCGUIElement) event.getTarget()); 
     565            } 
     566        } 
     567        else { 
     568            // a target was clicked repeatedly: 
     569            // the condensed sequence contains no mouseDowns or 
     570            // mouseUps anymore 
     571            // -> just generate another full click 
     572            generateFullClick(writer, event, (JFCGUIElement) event.getTarget()); 
     573        } 
     574 
     575    } 
     576 
     577    private void handleMouseDoubleClick(BufferedWriter writer, Event event) throws IOException { 
     578        StructureNode multiClick = structure.add("MultipleMouseClick"); 
     579 
     580        // first click 
     581        lastMouseClickEvent = multiClick.add("MouseClick"); 
     582        writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
     583                             DOUBLE_CLICK_DURATION, 501); 
     584        writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
     585                             DOUBLE_CLICK_DURATION, 502); 
     586        writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
     587                             DOUBLE_CLICK_DURATION, 500); 
     588        // second click 
     589        lastMouseClickEvent = multiClick.add("MouseClick"); 
     590        writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
     591                             DOUBLE_CLICK_DURATION, 501); 
     592        writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
     593                             DOUBLE_CLICK_DURATION, 502); 
     594        writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), 
     595                             DOUBLE_CLICK_DURATION, 500); 
     596 
     597        lastMouseClickEvent = null; 
     598 
     599    } 
     600 
     601    private void handleKeyboardFocusChange(BufferedWriter writer, Event event) throws IOException { 
     602        lastKeySequenceEvent = null; 
     603        writeFocusChangeEvent(writer, event); 
     604    } 
     605 
     606    private void handleMouseButtonDown(BufferedWriter writer, Event event) throws IOException { 
    395607        commitFocusEvent(); 
    396608        lastKeySequenceEvent = null; 
    397609 
    398         lastMouseClickEvent = new StructureNode(structureName); 
     610        lastMouseClickEvent = new StructureNode("MouseClick"); 
    399611        lastMouseDownTarget = event.getTarget(); 
    400612        writeMouseClickEvent(writer, event, (JFCGUIElement) event.getTarget(), EVENT_DURATION, 501); 
    401613    } 
    402614 
    403     private void handleMouseUp(BufferedWriter writer, Event event) throws IOException { 
     615    private void handleMouseButtonUp(BufferedWriter writer, Event event) throws IOException { 
    404616        lastKeySequenceEvent = null; 
    405617 
Note: See TracChangeset for help on using the changeset viewer.