예제 #1
0
  /**
   * See if the provided object reference has any children that may help satisfy the recognition
   * string. This is essentially how this Iterator is "reentrant". Objects matching pieces of our
   * ObjectVector are added to the statically shared matches collection until the final Object
   * satisfying the entire ObjectVector is found.
   *
   * <p>Throughout the process we must maintain an accurate count of each class and its associated
   * object type in each child branch. In this way, we keep track of when we have found the nth
   * Index of a class or an associated object type in the branch. Thus, for each object encountered,
   * we must increment both the class count, and t he object type count for that class in this
   * branch.
   *
   * <p>Note, as we go down an object hierarchy branch, the counts increment. However, when we reset
   * back up to a higher level in the object hierarchy to go down a new branch, the counts must be
   * reset to those counts that were valid on entry at that level.
   *
   * <p>This function is only called internally.
   *
   * <p>
   *
   * @param achild the Object to process for children.
   *     <p>
   * @param agovVector the currently active GuiObjectVector.
   *     <p>
   * @param agovLevel the hierarchy level in the GuiObjectVector we are trying to satisfy.
   *     <p>
   * @param aobjLevel the level in the actual object hierarchy we are searching.
   *     <p>
   * @param classindices the storage of current class counts.
   *     <p>
   * @param typeindices the storage of current object type counts.
   * @author Carl Nagle, SEP 02, 2004 modified processChildren to skip checking children of
   *     Comboboxes
   */
  protected void processChildren(
      Object achild,
      GuiObjectVector agovVector,
      int agovLevel,
      int aobjLevel,
      Hashtable classindices,
      Hashtable typeindices,
      String typeclass) {

    GuiObjectRecognition agor = agovVector.getParentGuiObjectRecognition();
    String classname = agor.getObjectClassName(achild);

    // CANAGL -- do not seek children in comboboxes.  messes pushbutton counts!
    try {
      if (GuiClassData.classtypeContainsClassType(typeclass, "ComboBox")) {
        Log.debug("GCI: No children sought for ComboBoxes");
        return;
      }
      // if Domain = HTML and typeclass = PushButton
      if ((classname.toLowerCase().startsWith("html"))
          && (GuiClassData.classtypeContainsClassType(typeclass, "PushButton"))) {
        Log.debug("GCI: No children sought for HTML PushButtons");
        return;
      }
    } catch (Exception x) {;
    }

    // may be cached keys to proxies during EXTERNAL_PROCESSING
    Object[] childsChildren = agovVector.getChildObjects(achild);

    if ((childsChildren instanceof Object) && (childsChildren.length > 0)) {

      Log.info("GCI: " + childsChildren.length + " children in " + classname);
      Log.info("..........Child:" + classname + ", typeclass: " + typeclass);
      GuiChildIterator it = agovVector.createGuiChildIterator(gather);

      boolean isTab =
          (GuiClassData.classtypeContainsClassType(typeclass, "TabControl"))
              || (GuiClassData.classtypeContainsClassType(classname, "Html.HtmlBrowser"));

      // childsChildren may be cached keys during EXTERNAL_PROCESSING
      it.processNextLevel(
          childsChildren, agovVector, agovLevel, aobjLevel, classindices, typeindices, isTab);
    } else {
      Log.debug("GCI: No children found for " + classname);
    }
  }
예제 #2
0
  /**
   * @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;
  }
예제 #3
0
  /**
   * 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);
      }
    }
  }