示例#1
0
  /**
   * Called internally by processChildren only.
   *
   * <p>
   *
   * @param children -- array of child objects to examine to see if any one of them satisfies the
   *     piece of the recognition string for the current object vector level--the current substring
   *     of the full recognition string. May be array of cached keys if GuiObjectVector is in
   *     EXTERNAL_PROCESSING_MODE.
   *     <p>
   * @param govVector -- the currently active GuiObjectVector.
   *     <p>
   * @param govLevel -- the hierarchy level (current substring)in the GuiObjectVector we are trying
   *     to satisfy.
   *     <p>
   * @param objLevel -- the depth in the actual application's object hierarchy currently being
   *     searched.
   *     <p>
   * @param entry_classindices -- the storage for class counts.
   *     <p>
   * @param entry_typeindices -- the storage for object type counts.
   *     <p>
   * @param onlyOneChildVisible -- true if parent is a TabControl-like component,
   */
  protected void processNextLevel(
      Object[] children, // children\key array to process
      GuiObjectVector govVector, // the full recognition vector
      int govLevel, // depth within the vector to process
      int objLevel, // depth within obj hierarchy being processed
      Hashtable entry_classindices, // class=count storage for class indices
      Hashtable entry_typeindices, // class=count storage for object indices
      boolean onlyOneChildVisible) { // if true, parent is tab
    boolean notDone = true;

    Hashtable classindices = entry_classindices;
    Hashtable typeindices = entry_typeindices;
    Hashtable save_classindices = (Hashtable) entry_classindices.clone();
    Hashtable save_typeindices = (Hashtable) entry_typeindices.clone();

    for (int i = 0; ((notFound) && (notDone) && (i < children.length)); i++) {

      Object _child = null;
      Object child = null;
      Object[] childsChildren = new Object[0];

      // reset indices for all but the last level of searching:
      // when dealing with things like TabControls with non-visible panels
      // and in CLASSIC_SEARCH_MODE.
      // In FULLPATH_SEARCH_MODE these hidden panels get unique indices
      if ((govLevel < govVector.getRecognitionDepth() - 1 && onlyOneChildVisible)
          && (SEARCH_MODE != FULLPATH_SEARCH_MODE)) {
        if (i > 0) {
          Log.info(".....class/type indices reset for all but the last level of searching");
          classindices = (Hashtable) save_classindices.clone();
          typeindices = (Hashtable) save_typeindices.clone();
        }
      }

      // get next child and reset index counters
      // only play with GuiTestObjects
      Log.info("GCI: Seeking child(" + i + ")outof(" + children.length + ")...");
      _child = children[i];
      child = _child;
      if (!govVector.isValidGuiObject(_child)) {
        Log.debug("GCI: skipping invalid Gui Object found in child array.");
        continue;
      }
      Log.info("GCI: child(" + i + ") is a valid GUI object.");

      if (govVector.getProcessMode() == GuiObjectVector.MODE_EXTERNAL_PROCESSING) {
        try {
          child = govVector.getCachedItem(_child);
        } catch (Exception e) {
        }
      }
      GuiObjectRecognition gor = govVector.getParentGuiObjectRecognition();
      String classname = gor.getObjectClassName(child);
      ClassTypeInfo typeinfo = null;

      // **** if (! classname.equalsIgnoreCase("Html.!")) { // this kills IE
      Log.info("GCI: child classname is:" + classname);

      // check to see if it is visible
      if (!gor.isObjectShowing(child)) {

        // if not, skip it if it is a container (like a TabControl Panel)
        Log.info("GCI: child is not showing.");
        if (govVector.isValidGuiContainer(_child)) {
          if (govVector.isFullPathSearchMode()) {
            incrementClassTypeIndices(
                child, govVector, govLevel, objLevel, classindices, typeindices, classname);
          }
          Log.info("GCI: skipping non-visible Gui Container: " + classname);
          continue;
        }
      }
      // } end if classname == "Html.!"
      typeinfo =
          incrementClassTypeIndices(
              child, govVector, govLevel, objLevel, classindices, typeindices, classname);
      if (typeinfo == null) continue; // invalid gorInfo at this level

      int classindex = typeinfo.classindex;
      int typeindex = typeinfo.typeindex;
      int abstypeindex = typeinfo.absolutetypeindex;
      String typeclass = typeinfo.typeclass;
      GuiObjectRecognition gorInfo = typeinfo.gorInfo;

      // classname  will ALWAYS have a class value
      // classindex will ALWAYS be at least 1
      // typeclass MAY BE null if we can't match the type
      // typeindex MAY BE  0   if we can't match the type
      int passindex, abspassindex;
      if (gorInfo.getClassCategoryID() == gorInfo.CATEGORY_CLASS_ID) {
        passindex = classindex;
        abspassindex = typeinfo.absoluteclassindex;
      }
      // TYPE is only alternative to CLASS right now
      else {
        passindex = typeindex;
        abspassindex = abstypeindex;
      }
      // see if we match the object at this level
      boolean classMatch;
      try {
        String[] tmpName = null;
        if (gather != null) tmpName = new String[1];
        classMatch =
            gorInfo.isMatchingObject(
                child, passindex,
                abspassindex, tmpName);

        // this is a special case test when we are doing this algorithm
        // but we want to gather *ALL* of the names which match, rather
        // than just the first name.  In that event, the parameter
        // 'gather' is used.  If not null, then don't let 'classMatch' get
        // beyond this place as 'true', but instead, stuff the name
        // into the List 'gather' and use 'false' for the classMatch...
        if (gather != null) {
          if (tmpName != null && tmpName[0] != null) {
            Log.info(" .....  ADD TO GATHER: " + tmpName[0]);
            gather.add(tmpName[0]);
          } else { // maybe use the index
            Log.info(
                " .....  GATHER INDEX?? passindex, abspassindex: "
                    + passindex
                    + ", "
                    + abspassindex
                    + ", classmatch would be: "
                    + classMatch);
          }
          // if we are gathering then lets also gather matched child objects
          if (classMatch) {
            // for recognitions with Path=, we must get that object
            // this is primarily used when we want ALL possible objects of
            // a given type.  For example, all HTMLLinks on a page.
            Object matchObject = gorInfo.getMatchingObject(child);
            MatchData adata = new MatchData(govVector, govLevel, objLevel, matchObject);
            matches.addElement(adata);
          }
          classMatch = false;
        }
      } catch (SAFSObjectRecognitionException ore) {
        classMatch = false;
        Log.debug(ore.getMessage());
      }

      if (classMatch) {
        // see if we have matched to the last object vector recognition level
        notDone = (govLevel < (govVector.getRecognitionDepth() - 1));
        Log.debug(
            "GCI: notDone matching vector: "
                + notDone
                + " :govLevel="
                + govLevel
                + ", maxLevel="
                + (govVector.getRecognitionDepth() - 1)
                + ", path="
                + govVector.getPathVector());
        if (notDone) {
          // see if this child has some children
          try {
            int lenchildren =
                (typeinfo.childsChildren != null)
                    ? typeinfo.childsChildren.length
                    : govVector.getChildObjects(child).length;
            if (lenchildren > 0) {
              // Log.index("notDone: processChildren: "+(objLevel+1));
              if (SEARCH_MODE == FULLPATH_SEARCH_MODE) {
                processChildren(
                    child,
                    govVector,
                    govLevel + 1,
                    objLevel + 1,
                    save_classindices,
                    save_typeindices,
                    typeclass);
              } else { // assume CLASSIC_SEARCH_MODE
                processChildren(
                    child,
                    govVector,
                    govLevel + 1,
                    objLevel + 1,
                    classindices,
                    typeindices,
                    typeclass);
              }
            }
            // if there are no children, then we are done going down this branch
            // and this path will not be a match for our recognition string
            else {
              // signal this branch is done
              // should this just be a continue?
              Log.debug("GCI: Branch completed. 0 children for " + gorInfo);
              notDone = false;
            }
            // signal this branch is done if no children (exception thrown for .length)
          } catch (Exception np) {
            Log.debug("GCI: Branch completed. NullPointer/No children for " + gorInfo, np);
            notDone = false;
          }
        }
        // **************************************************************
        // **** see if this is THEE child that completes our search! ****
        // **************************************************************
        else {
          hasFinalMatch = gorInfo.isFinalMatch(child);
          notFound = !hasFinalMatch;
          // for recognitions with Path=, we must get that object
          Object matchObject = gorInfo.getMatchingObject(child);
          // removing this unregister because currently unregistering any one reference
          // to an object seems to unregister ALL stored references to an object,
          // including cached references in our AppMaps.
          // // must unregister child if a subitem was actually the finalObject
          // if( !(matchObject == child)) {
          //   Log.debug("RGCI: Unregistering parent "+ child.getObjectClassName() +" from JVM as
          // needed.");
          //   child.unregister();
          // }
          //
          MatchData adata = new MatchData(govVector, govLevel, objLevel, matchObject);
          matches.addElement(adata);
        }
      }
      // not a class match for this object
      // we have to handle looking for the nth match inside a container
      // if not complete match, see if the match is farther down the hierarchy
      // but only for the CLASSIC_SEARCH_MODE.
      // We do not go down hierarchy paths for FULLPATH_SEARCH_MODE if the parent did not match
      else if (SEARCH_MODE
          != FULLPATH_SEARCH_MODE) { // will be CLASSIC_SEARCH_MODE (or anything else) by default
        // Log.index("processChildren: "+(objLevel+1));
        processChildren(
            child, govVector, govLevel, objLevel + 1, classindices, typeindices, typeclass);
      }
    } // end FOR LOOP
  }