// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.plugin.jfc.commands; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import de.ugoe.cs.autoquest.CommandHelpers; import de.ugoe.cs.autoquest.SequenceInstanceOf; import de.ugoe.cs.autoquest.eventcore.Event; import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel; import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; import de.ugoe.cs.autoquest.plugin.jfc.guimodel.JFCGUIElement; import de.ugoe.cs.autoquest.plugin.jfc.guimodel.JFCGUIElementSpec; import de.ugoe.cs.autoquest.plugin.jfc.guimodel.JFCMenu; import de.ugoe.cs.autoquest.plugin.jfc.guimodel.JFCMenuButton; import de.ugoe.cs.util.console.Command; import de.ugoe.cs.util.console.Console; import de.ugoe.cs.util.console.GlobalDataContainer; /** *

* Command to add an alternative index to JFCGuiElementSpecs. This index counts child type * separately. *

* * @author Daniel May */ public class CMDgenerateAltIndex implements Command { private List menuList; /* * (non-Javadoc) * * @see de.ugoe.cs.util.console.Command#run(java.util.List) */ @SuppressWarnings("unchecked") @Override public void run(List parameters) { String sequencesName = "sequences"; try { sequencesName = (String) parameters.get(0); if (parameters.size() >= 2) { menuList = Files.readAllLines(Paths.get((String) parameters.get(1)), Charset.defaultCharset()); } } catch (Exception e) { throw new IllegalArgumentException(); } Collection> sequences = null; Object dataObject = GlobalDataContainer.getInstance().getData(sequencesName); if (dataObject == null) { CommandHelpers.objectNotFoundMessage(sequencesName); return; } if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) { CommandHelpers.objectNotType(sequencesName, "Collection>>"); return; } sequences = (Collection>) dataObject; GUIModel model = null; for (List sequence : sequences) { if (model == null) { // generate jacareto indices for the GUI model of this sequence JFCGUIElement element = (JFCGUIElement) sequence.get(0).getTarget(); model = element.getGUIModel(); generateJacaretoIndices(model.getRootElements(), model); } else { for (Iterator eventIter = sequence.iterator(); eventIter.hasNext();) { // find and set the alt index for every target IGUIElement target = (IGUIElement) eventIter.next().getTarget(); findAltIndex(target, model.getRootElements(), model); } } } } private void findAltIndex(IGUIElement target, List elements, GUIModel model) { int altIndex = ((JFCGUIElementSpec) target.getSpecification()).getAltIndex(); if (altIndex < 0) { for (IGUIElement child : elements) { if (target.equals(child)) { int childAltIndex = ((JFCGUIElementSpec) child.getSpecification()).getAltIndex(); if (childAltIndex > -1) { ((JFCGUIElementSpec) target.getSpecification()).setAltIndex(childAltIndex); } else { findAltIndex(target, model.getChildren(child), model); } } else { findAltIndex(target, model.getChildren(child), model); } } } } /* * (non-Javadoc) * * @see de.ugoe.cs.util.console.Command#help() */ @Override public String help() { System.out.println("parseJFCDirwithJacaretoIndices {} {}"); return null; } private int findPopupMenuIndex(IGUIElement item, GUIModel model) { int index = -1; List children = model.getChildren(item); IGUIElement menuChild = null; // try to identify this popup menu by looking at its children // find the first menu item child of this item for (IGUIElement child : children) { if (child instanceof JFCMenuButton || child instanceof JFCMenu) { menuChild = child; break; } } if (menuChild == null) { // this popup menu cannot be identified Console.traceln(Level.WARNING, "Index for popup menu item could not be found."); return -1; } // find line that contains this menu item name String itemName = ((JFCGUIElement) menuChild).getName().trim().toLowerCase(); int lineOfItem = -1; for (int i = 0; i < menuList.size(); i++) { String name = "\"" + menuList.get(i).trim().toLowerCase() + "\""; if (name.equals(itemName)) { lineOfItem = i; break; } } if (lineOfItem == -1) { // failed to find this item in the menu file Console.traceln(Level.WARNING, "Menu file seems to be missing an item."); return -1; } // find menu item's parent line String stripped = menuList.get(lineOfItem).replaceFirst("^ *", ""); int indent = menuList.get(lineOfItem).length() - stripped.length(); if (indent != 0) { for (int i = lineOfItem; i >= 0; i--) { stripped = menuList.get(i).replaceFirst("^ *", ""); int oldIndent = menuList.get(i).length() - stripped.length(); if (oldIndent < indent) { lineOfItem = i; break; } } } // get the item's indentation stripped = menuList.get(lineOfItem).replaceFirst("^ *", ""); indent = menuList.get(lineOfItem).length() - stripped.length(); if (indent == 0) { // top level menu item, just count in which position it is for (int i = 0; i <= lineOfItem; i++) { if (!menuList.get(i).startsWith(" ")) { index++; } } } else { // find the topmenu index in the menu file by going backwards for (int i = lineOfItem; i >= 0; i--) { stripped = menuList.get(i).replaceFirst("^ *", ""); int oldIndent = menuList.get(i).length() - stripped.length(); if (oldIndent < indent) { index = lineOfItem - i; break; } } } return index; } private void generateJacaretoIndices(List elements, GUIModel targets) { HashMap typeCount = new HashMap<>(); for (IGUIElement child : elements) { String type = child.getSpecification().getType(); Integer count = typeCount.get(type); if (count == null) { count = 0; typeCount.put(type, count); } else { typeCount.put(type, ++count); } if (menuList != null && type.equals("javax.swing.JPopupMenu")) { // try to use a workaround for popup menu index problems int index = findPopupMenuIndex((IGUIElement) child, targets); if (index != -1) { ((JFCGUIElementSpec) child.getSpecification()).setAltIndex(index); } else { // workaround failed, use normal method as fallback ((JFCGUIElementSpec) child.getSpecification()).setAltIndex(count); } } else { ((JFCGUIElementSpec) child.getSpecification()).setAltIndex(count); } generateJacaretoIndices(targets.getChildren(child), targets); } } }