home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 25 / IOPROG_25.ISO / SOFT / JavaS / javastar-eval.exe / data1.cab / Program_Files / contrib / locators / ifc.java < prev    next >
Encoding:
Java Source  |  1999-02-11  |  18.6 KB  |  528 lines

  1. /*
  2.  *  @version             @(#)ifc.java    1.8 98/05/15
  3.  *
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package locators;
  21. import suntest.javastar.lib.*;
  22. import java.awt.*;
  23. import java.awt.event.*;
  24. import java.util.*;
  25. import java.lang.reflect.*;
  26. import locators.utils.IFC_Info;
  27.  
  28. /**
  29. * <ul>
  30. * <li>Non Component Locator for IFC toolkit
  31. * <li>Copyright (C) 1997 Sun Microsystem Inc.
  32. * <li>Netscape and IFC are registered trademarks of Netscape Corporation
  33. * </ul>
  34. * <p> The ifc class implements a nonComponent Locators solution for
  35. * Netscape's ifc
  36. * toolkit.  When used in conjunction with JavaStar the locator allows
  37. * JavaStar tests to operate in the ifc object level.  This version
  38. * of the locators support index, captions, and non hiearchical recording.
  39. * Index recording creates the tags by determining the index of a component
  40. * within its class.  For examples a TextField is the 2nd textfield in the
  41. * Container based upon its creation order.  A Caption of an ifc component
  42. * is when an object is of a certain class that contains a caption.  If
  43. * the caption is unique within the container instead of index JavaStar
  44. * will use the caption.  Non hiearchical recording occurs when a component
  45. * has a unique caption within the entire application.  In this case the
  46. * hiearchy does not have to be recorded.  When recording a test captions
  47. * take precedence over index.  If a component has a unique caption throughout
  48. * the application, the non-hiearchical tag is used.  When coding a script
  49. * manually any of these approaches may be utilized.
  50. *
  51. * @author     Dan Schaffer
  52. * @version    @(#)ifc.java    1.8 0
  53. */
  54. public class ifc implements JSNonComponentLocator {
  55.   /** the characters used to represent index separator */
  56.   public final static String INDEXSEP="%";
  57.   /** the characters used to represent caption separator */
  58.   public final static String CAPTIONSEP="^";
  59.  
  60.   /**
  61.    * Returns the non-component object and a string representation that
  62.    * is recreating by getNamedObjectData.  IFC does not support .getName.
  63.    * The possible tags are index based or caption based.  If the View
  64.    * (IFC component) has a .title() method the view title will be used
  65.    * otherwise the index will be used.
  66.    * @param    comp The AWT based Component or frame of IFC top level frame
  67.    *           in IFC its a Foundation Panel
  68.    * @param    e The AWTEvent, extract x,y coords
  69.    * @return   JSNCLData object is (String name,Point(widgets loc),Object)
  70.    * @see ifc#getNamedObjectData
  71.    */
  72.   public JSNCLData findObject(Component c, AWTEvent e){
  73.     if((c instanceof netscape.application.FoundationPanel)==false)
  74.       return null;
  75.     int x = ((MouseEvent)e).getX();
  76.     int y = ((MouseEvent)e).getY();
  77.     netscape.application.View v = getRoot(c);
  78.     netscape.application.View vm = v.viewForMouse(x,y);
  79.     vm=walkUpUntilEnabled(vm);
  80.     Vector vTree=buildTree(v);
  81.     IFC_Info nc=findView(vTree,vm);
  82.     if (nc==null)
  83.       return null;
  84.     String name=nc.theTag;
  85.     return new JSNCLData(name,locate(vm),vm);
  86.   }
  87.  
  88.  
  89.   /**
  90.    * Returns the non-component object after getting the actual View from
  91.    * the string description passed in.  Reconstructs the view from the
  92.    * text parameter.
  93.    *
  94.    * @param    c The AWT based Component in IFC its a FoundationPanel
  95.    * @param    name The name of the object
  96.    * @return   JSNCLData object is (String name,Point(widgets loc),Object)
  97.    * @see ifc#findObject
  98.    */
  99.   public JSNCLData getNamedObjectData(Component c, String name){
  100.     if((c instanceof netscape.application.FoundationPanel)==false)
  101.       return null;
  102.     netscape.application.View v=getRoot(c);
  103.  
  104.     // build entire tree
  105.     Vector vTree=buildTree(v);
  106.     // look in tree for the entry with name
  107.     IFC_Info nc=findTag(vTree,name);
  108.     if (isEnabled(nc.view)==false || isVisible(nc.view)==false)
  109.       return null;
  110.     // get the actual coordinates, return actual ifc component
  111.     return new JSNCLData(name,locate(nc.view),nc.view);
  112.   }
  113.  
  114.   /* Moves up the hiearchy until a component is enabled.
  115.    * @param v the object
  116.    * @returns View the first enabled object which could be and typically is
  117.    *    the parameter v.
  118.    */
  119.   public static netscape.application.View walkUpUntilEnabled(netscape.application.View v) {
  120.     boolean enabled=false;
  121.     while(enabled==false) {
  122.       enabled=isEnabled(v);
  123.       if (enabled==false) {
  124.     v=v.superview();
  125.     if (v==null)
  126.       return null;
  127.       }
  128.     }
  129.     return v;
  130.   }
  131.   /**
  132.    * determines whether a component is visible.  Reflection proved to be
  133.    * too slow.  The method checks to see the parameter is an instance of
  134.    * one the classes that defines isVisible.  Returns true if class is
  135.    * visible or if the class does not define visible.
  136.    * @param v the ifc view to check
  137.    * @returns boolean whether the object is visible or not
  138.    */
  139.   public static boolean isVisible(netscape.application.View v) {
  140.     boolean visible=true;
  141.     while (v!=null) {
  142.       if (v instanceof netscape.application.InternalWindow)
  143.     visible=((netscape.application.InternalWindow)v).isVisible();
  144.       else {
  145.     if (v instanceof netscape.application.RootView)
  146.       visible=((netscape.application.RootView)v).isVisible();
  147.     else {
  148.       if (v instanceof netscape.application.MenuView)
  149.         visible=((netscape.application.MenuView)v).isVisible();
  150.     }
  151.       }
  152.       if (visible==false)
  153.     return false;
  154.       v=v.superview();
  155.     }
  156.     return visible;
  157.   }
  158.   /**
  159.    * determines whether a component is enabled.  Reflection proved to be
  160.    * too slow.  The method checks to see the parameter is an instance of
  161.    * one the classes that defines isEnabled.  Returns true if class is
  162.    * enabled or if the class does not define isEnabled.
  163.    * @param v the ifc view to check
  164.    * @returns boolean whether the object is enabled or not
  165.    */
  166.   public static boolean isEnabled(netscape.application.View v) {
  167.     boolean enabled=true;
  168.     if (v instanceof netscape.application.Button)
  169.       enabled=((netscape.application.Button)v).isEnabled();
  170.     else {
  171.       if (v instanceof netscape.application.DragWell)
  172.     enabled=((netscape.application.DragWell)v).isEnabled();
  173.       else {
  174.     if (v instanceof netscape.application.ListView)
  175.       enabled=((netscape.application.ListView)v).isEnabled();
  176.     else {
  177.       if (v instanceof netscape.application.ScrollBar)
  178.         enabled=((netscape.application.ScrollBar)v).isEnabled();
  179.       else {
  180.         if (v instanceof netscape.application.Slider)
  181.           enabled=((netscape.application.Slider)v).isEnabled();
  182.       }
  183.     }
  184.       }
  185.     }
  186.     return enabled;
  187.   }
  188.   /**
  189.    * gets the class name of the object.
  190.    * @param o the object
  191.    * @returns the class name as a string
  192.    */
  193.   public static String getClassName(Object o){
  194.     String cl = o.getClass().getName();
  195.     return cl;
  196.   }
  197.   /**
  198.    * gets the class name of the object in a short version.  The package
  199.    * name is removed.  All text after the "." is returned
  200.    * @param o the object
  201.    * @returns the class name as a string
  202.    */
  203.   public static String getClassNameShort(Object o) {
  204.     String cl = o.getClass().getName();
  205.     return cl.substring(1+cl.lastIndexOf('.'));
  206.   }
  207.  
  208.   /**
  209.    * find the x,y location of the view relative to the Foundation Panel
  210.    * get the coordinates of ancestry to determine absolute location
  211.    * The methods walks up the hiearchy added each components relative
  212.    * locations to calculate the global coordinate within the top level
  213.    * ifc component.
  214.    * @param rv the view to start with
  215.    * @returns the Point
  216.    */
  217.   public static Point locate(netscape.application.View rv){
  218.     Point p=new Point(0,0);
  219.     while (rv!=null) {
  220.       p=new Point(p.x+rv.x(),p.y+rv.y());
  221.       rv=rv.superview();
  222.     }
  223.     return p;
  224.   }
  225.   /**
  226.   * Searches the widget for a child widget matching the class.  Returns
  227.   * the widget when find the child widget with the correct index
  228.   * @param w the ifc component
  229.   * @param cname the matching class name
  230.   * @param index the index of the classname to find
  231.   * @returns View the object matching the criteria
  232.   */
  233.   public static netscape.application.View findIndexView(netscape.application.View w,String cname,int index) {
  234.     int iNum=0;
  235.     netscape.util.Vector v=w.subviews();
  236.     for (int i=0;i<v.size();i++){
  237.       if (getClassNameShort(v.elementAt(i)).equals(cname))
  238.     iNum++;
  239.       if (iNum>index)
  240.     return (netscape.application.View)v.elementAt(i);
  241.     }
  242.     return null;
  243.   }
  244.   /**
  245.    * Creates a string representation of the widget.  For each level in
  246.    * the widget hiearchy get the index of the component and the class.
  247.    * for each level create <classname>%<index>.  The "." separates each
  248.    * widget.
  249.    * @param w the View of the object
  250.    * @returns String the string representation of the tag
  251.    */
  252.   public static String buildTag(netscape.application.View w) {
  253.     int index;
  254.     String sRet="",s;
  255.     // starting at top get the widget class,index append to tag and walk
  256.     // down to top level where w.parent is null
  257.     // if can't find a component is the parent list return null
  258.     while (w!=null) {
  259.       s=getClassNameShort(w);
  260.       if (w.superview()!=null) {
  261.     index=getViewIndex(w);
  262.     if (index!= -1)
  263.       s+=INDEXSEP+index;
  264.       }
  265.       if (sRet=="")
  266.     sRet=s;
  267.       else
  268.     sRet=s+"."+sRet;
  269.       w=w.superview();
  270.     }
  271.     return sRet;
  272.   }
  273.   /**
  274.    * gets the index of a component by counting the number of object with
  275.    * the same class name that the parent contains.  The index count of
  276.    * the number of objects created by the current component of the same
  277.    * class +1.
  278.    * @param w the object
  279.    * @returns int the index of the object
  280.    */
  281.   public static int getViewIndex(netscape.application.View w) {
  282.     netscape.application.View container=w.superview();
  283.     int index=0;
  284.     if (container==null)
  285.       return -1;
  286.     netscape.util.Vector v=container.subviews();
  287.     for (int i=0;i<v.size();i++) {
  288.       if (v.elementAt(i)==w)
  289.     return index;
  290.       if (v.elementAt(i).getClass()==w.getClass())
  291.     index++;
  292.     }
  293.     return -1;
  294.   }
  295.  
  296.   /** Checks to see if the view has a title method.  Reflection
  297.    * proved to be too slow.  The method checks if the object is
  298.    * an instance of a class that defines the title() method.  If
  299.    * not the method returns null otherwise returns the title
  300.    * or caption of the view.
  301.    * @param w the object
  302.    * @returns String the caption of null if one is not available
  303.   */
  304.   public static String getViewCaption(netscape.application.View w) {
  305.     String sRet=null;
  306.     String theClass;
  307.     if (w instanceof netscape.application.Button)
  308.       sRet=((netscape.application.Button)w).title();
  309.     else {
  310.       if (w instanceof netscape.application.Label)
  311.     sRet=((netscape.application.Label)w).title();
  312.       else {
  313.     if (w instanceof netscape.application.ContainerView)
  314.       sRet=((netscape.application.ContainerView)w).title();
  315.     else {
  316.       if (w instanceof netscape.application.InternalWindow)
  317.         sRet=((netscape.application.InternalWindow)w).title();
  318.     }
  319.       }
  320.     }
  321.     if (sRet==null || sRet=="")
  322.       return null;
  323.     return sRet;
  324.   }
  325.   /**
  326.   * returns the top level ifc component based upon a FoundationPanel.
  327.   * The parameter is a Component that is casted into a FoundationPanel.
  328.   * @param c the top level Component (FoundationPanel)
  329.   * @returns the top level view
  330.   */
  331.   public static netscape.application.View getRoot(Component c) {
  332.     netscape.application.FoundationPanel fp=(netscape.application.FoundationPanel)c;
  333.     return (netscape.application.View)fp.rootView();
  334.   }
  335.   /**
  336.   * returns the top level ifc component based upon a view
  337.   * @param w one of the children
  338.   * @returns the top level view
  339.   */
  340.   public static netscape.application.View getRoot(netscape.application.View w) {
  341.     netscape.application.View wlast=w;
  342.     if (w==null)
  343.       return null;
  344.     return w.rootView();
  345.   }
  346.   /** searches through the widget tree for widget with the tag (String)
  347.   * returns the IFC_Info datatype
  348.   * @param v the widget tree
  349.   * @param s the search tag
  350.   * @returns IFC_Info the data structure containing the desired component
  351.   *    information
  352.   */
  353.   public static IFC_Info findTag(Vector v,String s) {
  354.     IFC_Info wi;
  355.     if (s.startsWith("root")) {
  356.       if (s.indexOf(".")== -1)
  357.     return null;
  358.       s="RootView"+s.substring(s.indexOf("."));
  359.     }
  360.     for (int i=0;i<v.size();i++) {
  361.       wi=(IFC_Info)v.elementAt(i);
  362.       if (wi.theTag.equals(s) || (wi.parent+"."+wi.className+INDEXSEP+wi.index).equals(s) || (wi.caption!=null && (wi.parent+"."+wi.className+CAPTIONSEP+wi.caption+CAPTIONSEP).equals(s))) {
  363.     return wi;
  364.       }
  365.     }
  366.     return null;
  367.   }
  368.   /**
  369.   * searches through widget tree for a view
  370.   * @param v the widget tree
  371.   * @param w the view to search for
  372.   * @returns IFC_Info the data structure containing the desired component
  373.   *    information
  374.   */
  375.   public static IFC_Info findView(Vector v,netscape.application.View w) {
  376.     IFC_Info wi;
  377.     for (int i=0;i<v.size();i++) {
  378.       wi=(IFC_Info)v.elementAt(i);
  379.       if (wi.view==w)
  380.     return wi;
  381.     }
  382.     return null;
  383.   }
  384.   /**
  385.    * creates a Vector of the entire component hierarchy.  Each ifc view
  386.    * is added to the Vector.  Inside the data structure contains all the
  387.    * information necessary to calculate whether the component is unique
  388.    */
  389.   public static Vector buildTree(netscape.application.View vRoot) {
  390.     int index,i;
  391.     Hashtable vIntName=new Hashtable();
  392.     Hashtable vCaption=new Hashtable();
  393.     Vector vRet=new Vector();
  394.     Vector vCon=new Vector();
  395.     IFC_Info w,wi;
  396.     Hashtable classTable=new Hashtable();
  397.     vCon.addElement(new IFC_Info(vRoot,null));
  398.     while (vCon.isEmpty()==false) {
  399.       w=(IFC_Info)vCon.firstElement();
  400.       vCon.removeElementAt(0);
  401.  
  402.       w.className=getClassNameShort(w.view);
  403.       w.index=getViewIndex(w.view);
  404.       w.caption=getViewCaption(w.view);
  405.       if (w.caption!=null) {
  406.     w.localTagName=w.className+CAPTIONSEP+w.caption+CAPTIONSEP;
  407.     w.fullTagName=w.localTagName;
  408.     if (w.parent!=null) {
  409.       w.fullTagName=w.parent+"."+w.fullTagName;
  410.     }
  411.       }
  412.       else {
  413.     w.localTagName=null;
  414.     if (w.index != -1) {
  415.       w.fullTagName=w.className+INDEXSEP+w.index;
  416.     } else {
  417.       w.fullTagName=w.className;
  418.     }
  419.     if (w.parent!=null) {
  420.       w.fullTagName=w.parent+"."+w.fullTagName;
  421.     }
  422.       }
  423.       if (w.caption!=null) {
  424.     if (vCaption.get(w.localTagName)!=null) {
  425.       i=((Integer)vCaption.get(w.localTagName)).intValue();
  426.       wi=(IFC_Info)vRet.elementAt(i);
  427.       wi.localTagName=null;
  428.       wi.setTheTag();
  429.       vRet.setElementAt(wi,i);
  430.       w.localTagName=null;
  431.     } else {
  432.       vCaption.put(w.localTagName,new Integer(vRet.size()));
  433.       vCaption.put(w.fullTagName,new Integer(vRet.size()));
  434.     }
  435.     if (w.localTagName==null) {
  436.       if (vCaption.get(w.fullTagName)!=null) {
  437.         i=((Integer)vCaption.get(w.fullTagName)).intValue();
  438.         wi=(IFC_Info)vRet.elementAt(i);
  439.         wi.fullTagName=wi.className+INDEXSEP+wi.index;
  440.         if (wi.parent!=null) {
  441.           wi.fullTagName=wi.parent+"."+wi.fullTagName;
  442.         }
  443.         wi.setTheTag();
  444.         vRet.setElementAt(wi,i);
  445.         w.fullTagName=w.className+INDEXSEP+w.index;
  446.         if (w.parent!=null) {
  447.           w.fullTagName=w.parent+"."+w.fullTagName;
  448.         }
  449.       }
  450.     }
  451.       }
  452.       w.setTheTag();
  453.       vRet.addElement(w);
  454.       netscape.util.Vector vList=w.view.subviews();
  455.       for (i=0;i<vList.size();i++)
  456.     vCon.addElement(new IFC_Info((netscape.application.View)vList.elementAt(i),w.fullTagName));
  457.     }
  458.     return vRet;
  459.   }
  460.   /**
  461.    * removes a marker such as '%' '^' from beginning and end of string
  462.    * also if the marker exists in the string unescapes it
  463.    * @param tag the source string
  464.    * @param marker the string to remove
  465.    * @returns String the source with all markers removed
  466.    */
  467.   public static String removeMarkers(String tag,String marker) {
  468.     if (tag.startsWith(marker))
  469.       tag=tag.substring(1);
  470.     if (tag.endsWith(marker))
  471.       tag=tag.substring(0,tag.length()-1);
  472.     tag=replaceString(tag,marker+marker,marker);
  473.     return tag;
  474.   }
  475.   /** adds a marker such as '%' '^' to beginning and end of string
  476.    * also if the marker exists in the string makes it "%%" to escape
  477.    * the marker
  478.    * @param tag the source string
  479.    * @marker the marker to add
  480.    * @returns String the source string with markers added on either end and
  481.    *    all occurrences of the marker is replaced with two markers to escape
  482.    *    the string
  483.    */
  484.   public static String addMarkers(String tag,String marker) {
  485.     tag=replaceString(tag,marker,marker+marker);
  486.     tag=marker+tag+marker;
  487.     return tag;
  488.   }
  489.   /**
  490.   * replaces all occurrences of replace with replaceWith
  491.   * @param s the source string
  492.   * @param replace the string to replace
  493.   * @param replaceWith the string to replace with
  494.   * @returns String the source string with all occurrences of string replaced
  495.   */
  496.   public static String replaceString(String s,String replace,String replaceWith) {
  497.     int index=0;
  498.     for (index=s.indexOf(replace,index);index!= -1;) {
  499.       s=s.substring(0,index)+replaceWith+s.substring(index+replace.length());
  500.       index=index-replace.length()+replaceWith.length()+1;
  501.       index=s.indexOf(replace,index);
  502.     }
  503.     return s;
  504.   }
  505.   /** Used for Debugging purpose.  Outputs to stdout the entire tree.
  506.    * this is really going to hurt performance but is useful for debugging
  507.    * purpose.
  508.    * @param vWid the widget tree to print out
  509.    */
  510.   public static void printTree(netscape.application.FoundationPanel fp) {
  511.     Vector vWid=buildTree(getRoot(fp));
  512.     printTree(vWid);
  513.   }
  514.   /** Used for Debugging purpose.  Outputs to stdout the entire tree.
  515.    * this is really going to hurt performance but is useful for debugging
  516.    * purpose.
  517.    * @param vWid the widget tree to print out
  518.    */
  519.   public static void printTree(Vector vWid) {
  520.     IFC_Info wi;
  521.     for (int i=0;i<vWid.size();i++) {
  522.       wi=(IFC_Info)vWid.elementAt(i);
  523.       System.out.println(wi);
  524.     }
  525.   }
  526.  
  527. }
  528.