/** * @param child * @param govVector * @param objLevel * @param govLevel * @param classindices * @param typeindices * @param classname * @return NULL if error occurs relating to gorInfo creation, or NULL if object is NOT to be * processed. Otherwise, return a valid ClassTypeInfo object with all appropriate settings. */ protected ClassTypeInfo incrementClassTypeIndices( Object child, GuiObjectVector govVector, int govLevel, int objLevel, Hashtable classindices, Hashtable typeindices, String classname) { Log.info("GCI: getting child GOR info. GOV level:" + govLevel); ClassTypeInfo cti = new ClassTypeInfo(); final String TOOLTIP_SUFFIX = "TOOLTIP"; cti.classname = classname; try { cti.gorInfo = govVector.getChildGuiObjectRecognition(govLevel); } catch (ArrayIndexOutOfBoundsException x) { Log.debug( "GCI: sought govLevel:" + govLevel + ", exceeds 0-based recognition path information:" + govVector.getPathVector()); return null; } GuiClassData classdata = govVector.getGuiClassData(); cti.typeclass = classdata.getMappedClassType(classname, child); // bypass panels that harbor tooltip(s) Object tooltip = null; String tooltipclass = null; String tooltipmapped = null; String gortypeclass = cti.gorInfo.getClassValue(); // only perform check if we are NOT looking for a tooltip if ((gortypeclass == null) || (gortypeclass != null && !gortypeclass.toUpperCase().endsWith(TOOLTIP_SUFFIX))) { try { Log.info("GCI.incrementClassTypeIndices evaluating possible TOOLTIP container..."); if (classdata.isToolTipContainerType(cti.typeclass)) { Object[] childsChildren = govVector.getChildObjects(child); if (childsChildren != null && childsChildren.length > 0) { tooltip = childsChildren[0]; tooltipclass = cti.gorInfo.getObjectClassName(tooltip); try { if (tooltipclass.toUpperCase().endsWith(TOOLTIP_SUFFIX)) { Log.info("GCI.incrementClassTypeIndices bypassing active TOOLTIP class!"); return null; // skip panel with tooltip } tooltipmapped = classdata.getMappedClassType(tooltipclass, tooltip); if (tooltipmapped.toUpperCase().endsWith(TOOLTIP_SUFFIX)) { Log.info("GCI.incrementClassTypeIndices bypassing active TOOLTIP type!"); return null; // skip panel with tooltip } } catch (Exception x) { Log.debug( "GCI.incrementClassTypeIndices ToolTip test IGNORING " + x.getClass().getSimpleName()); } } } Log.info("GCI.incrementClassTypeIndices container NOT a TOOLTIP container."); } catch (Exception x) { Log.debug( "GCI.incrementClassTypeIndices ToolTip Container test IGNORING " + x.getClass().getSimpleName()); } } // increment class index counters for the retrieved class? Log.info("GCI: incrementing class indices for:" + classname); Integer classindex = (Integer) classindices.get(classname); classindex = (classindex == null) ? new Integer(1) : new Integer(classindex.intValue() + 1); classindices.put(classname, classindex); cti.classindex = classindex.intValue(); Log.info("GCI: classindices.put(" + classname + ", " + classindex + ")"); Integer absclassindex = (Integer) absindices.get(classname); absclassindex = (absclassindex == null) ? new Integer(1) : new Integer(absclassindex.intValue() + 1); absindices.put(classname, absclassindex); cti.absoluteclassindex = absclassindex.intValue(); Log.info("GCI: absindices.put(" + classname + ", " + absclassindex + ")"); // also increment the Type index counter if it is equivalent to a known type String gorClassType = cti.gorInfo.getClassValue(); Log.info("GCI: " + classname + " mappedClassType: " + cti.typeclass); Integer typeindex = new Integer(0); Integer abstypeindex = new Integer(0); if (cti.typeclass instanceof String) { StringTokenizer toker = new StringTokenizer(cti.typeclass, classdata.DEFAULT_TYPE_SEPARATOR); String atoken = null; Integer tmptypeindex = null; Integer tmpabstypeindex = null; while (toker.hasMoreTokens()) { atoken = toker.nextToken().toUpperCase().trim(); tmptypeindex = (Integer) typeindices.get(atoken); Log.info("GCI: getting: " + atoken + ", " + tmptypeindex); tmptypeindex = (tmptypeindex == null) ? new Integer(1) : new Integer(tmptypeindex.intValue() + 1); Log.index( "GCI: ... " + StringUtils.getSpaces(new Integer(objLevel)) + atoken + ":" + tmptypeindex); typeindices.put(atoken, tmptypeindex); tmpabstypeindex = (Integer) absindices.get(atoken); tmpabstypeindex = (tmpabstypeindex == null) ? new Integer(1) : new Integer(tmpabstypeindex.intValue() + 1); absindices.put(atoken, tmpabstypeindex); Log.info("TYPE:absindices.put(" + atoken + ", " + tmpabstypeindex + ")"); // use the correct typeindex for the classtype that matches recognition string if (atoken.equalsIgnoreCase(gorClassType)) { typeindex = tmptypeindex; cti.typeindex = typeindex.intValue(); abstypeindex = tmpabstypeindex; cti.absolutetypeindex = abstypeindex.intValue(); } } } return cti; }
/** * Called only once by some external routine kicking off a TestObject search. The govLevel and * objLevel in the ObjectVector will be assumed to be 0. The routine will install an initial class * and type indices for the provided parent. * * <p>If we can deduce that the parent actually exists in the path vector then that govLevel of * the vector will be matched and skipped. If we find that the parent info is NOT in the provided * vector then we will not skip the govLevel. * * <p>We can assume the parent info is in the path if the path begins with "\;". The next item in * the path is assumed to be the topmost parent. * * <p>We can ignore the first path info if it instead begins with ".\;". The next item would be * considered to be the first child of the parent. * * <p> * * @param aparent the topmost parent to search. * <p> * @param agovVector the govVector (recognition string) to satisfy with the search. * <p> * @param gather, List containing names matched, if null, then match first name */ public GuiChildIterator(Object aparent, GuiObjectVector agovVector, java.util.List gather) { this(gather); if (agovVector.isFullPathSearchMode()) { setSearchMode(FULLPATH_SEARCH_MODE); } else { setSearchMode(CLASSIC_SEARCH_MODE); } Hashtable classindices = new Hashtable(8); Hashtable typeindices = new Hashtable(8); matches = new Vector(10, 3); notFound = true; hasFinalMatch = false; // class (ex: JFrame) and Type (ex: Window) counters are complimentary // for each class that is a known type BOTH counters get incremented. // always initialize class index counters for the retrieved class // it is possible this "parent" info is actually info for the first child govLevel 0 GuiObjectRecognition gorParent = agovVector.getParentGuiObjectRecognition(); GuiClassData classdata = agovVector.getGuiClassData(); String classname = gorParent.getObjectClassName(aparent); Log.info("GCI: processing children of parent:" + classname); classindices.put(classname, new Integer(1)); // always initialize the Type index counter if it is equivalent to a known type String typeclass = classdata.getMappedClassType(classname, aparent); Log.info("GCI: processing parent of type:" + typeclass); if (typeclass instanceof String) { StringTokenizer toker = new StringTokenizer(typeclass, classdata.DEFAULT_TYPE_SEPARATOR); String atoken = null; while (toker.hasMoreTokens()) { atoken = toker.nextToken().trim(); typeindices.put(atoken, new Integer(1)); } } // add our entry govVector and parent object as the first match // CANAGL - modifying to only store finalMatches // MatchData adata = new MatchData(agovVector, 0, 0, aparent); // matches.addElement(adata); int agovDepth = agovVector.getRecognitionDepth(); Log.info( "GCI: processing GOV with depth of:" + agovDepth + ", path=" + agovVector.getPathVector()); // begin the reentrant search for the matching child int startlevel = (agovDepth > 1) ? 1 : 0; if ((gorParent.getGovLevel() == 0) && (!(gorParent.pathInfo.equals(GuiObjectVector.ACTIVE_WINDOW_REFERENCE)))) { // Robot Java recognition strings often contain a JavaWindow reference // to the parent window that needs to be skipped. Same with Flex recognition strings(JunwuMa). if (!gorParent.getClassRecognition().equalsIgnoreCase("Type=JavaWindow") && !gorParent.getClassRecognition().equalsIgnoreCase("Type=FlexWindow")) { startlevel = 0; } else { Log.info( "GCI: bypassing govLevel=0 for child 'Type=JavaWindow'. Assuming duplicate parent info."); } } // Try to match the parent for some popupmenu Hashtable save_classindices = (Hashtable) classindices.clone(); Hashtable save_typeindices = (Hashtable) typeindices.clone(); processParent(aparent, agovVector, startlevel, 1, classindices, typeindices, typeclass); Object matchedObject = this.getMatchedGuiObject(); if (matchedObject == null) { if (SEARCH_MODE != FULLPATH_SEARCH_MODE) { Log.info("GCI: CLASSIC_SEARCH_MODE calling processChildren..."); processChildren(aparent, agovVector, startlevel, 1, classindices, typeindices, typeclass); } else { Log.info("GCI: FULLPATH_SEARCH_MODE calling processChildren..."); processChildren( aparent, agovVector, startlevel, 1, save_classindices, save_typeindices, typeclass); } } }