< prev index next >

core/JemmyCore/src/org/jemmy/lookup/AbstractLookup.java

Print this page




  24  */
  25 package org.jemmy.lookup;
  26 
  27 import java.io.PrintStream;
  28 import java.util.List;
  29 import org.jemmy.interfaces.*;
  30 import java.util.ArrayList;
  31 import java.util.HashMap;
  32 import java.util.Map;
  33 import org.jemmy.control.Wrap;
  34 import org.jemmy.control.Wrapper;
  35 import org.jemmy.env.Environment;
  36 import org.jemmy.env.TestOut;
  37 import org.jemmy.timing.State;
  38 
  39 /**
  40  * Default implementation of Lookup. Regularly, it is enough just override this
  41  * implementation and allow it to handle sub-lookups creation.
  42  * @see AbstractLookup#lookup(org.jemmy.lookup.LookupCriteria)
  43  * @see AbstractLookup#lookup(java.lang.Class, org.jemmy.lookup.LookupCriteria)
  44  * @param <CONTROL>
  45  * @author shura
  46  */
  47 public abstract class AbstractLookup<CONTROL> extends AbstractParent<CONTROL> implements Lookup<CONTROL> {
  48 
  49     static final String PREFIX_DELTA = "| ";
  50     private ArrayList<CONTROL> found;
  51     Environment env;
  52     private Class<CONTROL> clss;
  53     private LookupCriteria<CONTROL> criteria = null;
  54     private Wrapper wrapper;
  55 
  56     /**
  57      * Identifies output where lookup progress is printed.
  58      * @see Environment#getOutput(java.lang.String)
  59      * @see AbstractLookup#wait(int)
  60      * @see AbstractLookup#size()
  61      */
  62     public static final String OUTPUT = AbstractLookup.class.getName() + ".OUTPUT";
  63 
  64 
  65     static {
  66         Environment.getEnvironment().initTimeout(WAIT_CONTROL_TIMEOUT);
  67         Environment.getEnvironment().initOutput(OUTPUT, TestOut.getNullOutput());
  68     }
  69 
  70     /**
  71      * This actual lookup logic is delegated to <code>getCildren(java.lang.Object)</code>
  72      * method
  73      * @see AbstractLookup#getChildren(java.lang.Object)
  74      * @param env
  75      * @param controlClass
  76      * @param criteria
  77      * @param wrapper
  78      */
  79     public AbstractLookup(Environment env, Class<CONTROL> controlClass, LookupCriteria<CONTROL> criteria, Wrapper wrapper) {
  80         this.env = env;
  81         found = new ArrayList<CONTROL>();
  82         this.clss = controlClass;
  83         this.criteria = criteria;
  84         this.wrapper = wrapper;
  85     }
  86 
  87     Wrapper getWrapper() {
  88         return wrapper;
  89     }
  90 
  91     /**
  92      *
  93      * @return
  94      */
  95     LookupCriteria<CONTROL> getCriteria() {
  96         return criteria;
  97     }
  98 
  99     /**
 100      *
 101      * @return
 102      */
 103     Environment getEnvironment() {
 104         return env;
 105     }
 106 
 107     /**
 108      *
 109      * @return The class of the sount controls.
 110      */
 111     Class<CONTROL> getControlClass() {
 112         return clss;
 113     }
 114 
 115     public <T extends CONTROL> Lookup<T> lookup(Class<T> controlClass, LookupCriteria<T> criteria) {
 116         return new ClassLookupImpl<CONTROL, T>(env, this, controlClass, criteria, wrapper);
 117     }
 118 
 119     public Lookup<CONTROL> lookup(LookupCriteria<CONTROL> criteria) {
 120         return new ClassLookupImpl<CONTROL, CONTROL>(env, this, clss, criteria, wrapper);
 121     }
 122 
 123     /**
 124      * Waits for certain number of controls to fit criteria.
 125      * Depending on how outputs set, prints out info about the lookup.
 126      * @param count
 127      * @return this, after the count of found number of found controls
 128      * exceeds the required.
 129      * @see AbstractLookup#OUTPUT
 130      */
 131     public Lookup<? extends CONTROL> wait(final int count) {
 132         getEnvironment().getOutput(OUTPUT).println("Waiting for " + count + " controls of " + clss.getName() + " class fitting criteria " + criteria);
 133         env.getWaiter(Lookup.WAIT_CONTROL_TIMEOUT.getName()).ensureState(new State<Integer>() {
 134 
 135             public Integer reached() {
 136                 if(found.size() < count)
 137                     refresh();
 138                 return (found.size() >= count) ? found.size() : null;
 139             }
 140 
 141             @Override
 142             public String toString() {
 143                 return "Waiting for " + count + " " + clss.getName() + " controls to be found adhering to "
 144                         + criteria;
 145             }
 146 
 147         });
 148         return this;
 149     }
 150 
 151     /**
 152      * Gets the number of controls which fit criteria.
 153      * Depending on how outputs set, prints out info about the lookup.
 154      * @see AbstractLookup#OUTPUT
 155      * @return
 156      */
 157     public int size() {
 158         getEnvironment().getOutput(OUTPUT).println("Getting number of controls of " + clss.getName() + " class fitting criteria " + criteria);
 159         refresh();
 160         return found.size();
 161     }
 162 
 163     /**
 164      *
 165      */
 166     void refresh() {
 167         found.clear();
 168         List childen = getChildren(null);
 169         if (childen != null) {
 170             for (Object c : childen) {
 171                 add(c);
 172             }
 173         }
 174     }
 175 
 176     @SuppressWarnings("element-type-mismatch")
 177     private void add(Object subparent) {
 178         if (subparent != null/* && !found.contains(subparent)*/) {
 179             if (clss.isInstance(subparent) && check(clss.cast(subparent))) {
 180                 found.add(clss.cast(subparent));
 181             }
 182             List childen = getChildren(subparent);
 183             if (childen != null) {
 184                 for (Object child : childen) {
 185                     add(child);
 186                 }
 187             }
 188         }
 189     }
 190 
 191     /**
 192      *
 193      * @param control
 194      * @return
 195      */
 196     protected boolean check(CONTROL control) {
 197         return control != null && criteria.check(control);
 198     }
 199 
 200     /**
 201      * Returns Wrap of the control with specified index
 202      * @param index
 203      * @return Wrap
 204      */
 205     public Wrap<? extends CONTROL> wrap(int index) {
 206         return instantiate(get(index));
 207     }
 208 
 209     /**
 210      *
 211      * @return
 212      */
 213     public Wrap<? extends CONTROL> wrap() {
 214         return wrap(0);
 215     }
 216 
 217     /**
 218      * @{inheritDoc}
 219      */
 220     public <INTERFACE extends ControlInterface> INTERFACE as(int index, Class<INTERFACE> interfaceClass) {
 221         return wrap(index).as(interfaceClass);
 222     }
 223 
 224     /**
 225      * @{inheritDoc}
 226      */
 227     public <INTERFACE extends ControlInterface> INTERFACE as(Class<INTERFACE> interfaceClass) {
 228         return as(0, interfaceClass);
 229     }
 230 
 231     /**
 232      * @{inheritDoc}
 233      */
 234     public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> INTERFACE as(int index, Class<INTERFACE> interfaceClass, Class<TYPE> type) {
 235         return wrap(index).as(interfaceClass, type);
 236     }
 237 
 238     /**
 239      * @{inheritDoc}
 240      */
 241     public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> INTERFACE as(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
 242         return as(0, interfaceClass, type);
 243     }
 244 
 245     public CONTROL get(int index) {
 246         wait(index + 1);
 247         return found.get(index);
 248     }
 249 
 250     /**
 251      * @{inheritDoc}
 252      */
 253     public CONTROL get() {
 254         return get(0);
 255     }
 256 
 257     /**
 258      *
 259      * @return
 260      */
 261     List<CONTROL> getFound() {
 262         return found;
 263     }
 264 
 265     /**
 266      *
 267      * @return
 268      */
 269     public Class<CONTROL> getType() {
 270         return getControlClass();
 271     }
 272 
 273     /**
 274      * Override this to get subchildren of the controls in the hierarchy.
 275      * List could contain any type of objects - not just <code>CONTROL</code>.
 276      * @param subParent - one of the elements in the hierarchy reflected by this lookup.
 277      * If null passed - first level children are expected.
 278      * @return
 279      */
 280     abstract List getChildren(Object subParent);
 281 
 282     private String buildClassChain(Class cls) {
 283         StringBuilder sb = new StringBuilder(cls.getName());
 284         if (getType().isInterface()) {
 285             sb.append(" implements ").append(getType().getName());
 286         } else {
 287             do {
 288                 cls = cls.getSuperclass();
 289                 sb.append(" <- ").append(cls.getName());
 290             } while (!cls.equals(getType()) && !cls.equals(Object.class));
 291         }
 292         return sb.toString();
 293     }
 294 
 295     /**
 296      * Wraps the control with a <code>Wrap</code> class.
 297      * @see Wrap
 298      * @param wrap
 299      * @return Wrap
 300      */
 301     private Wrap<? extends CONTROL> instantiate(CONTROL control) {
 302         return wrapper.wrap(clss, control);
 303     }
 304 
 305     /**
 306      *
 307      * @param out
 308      * @param obj
 309      * @param prefix
 310      */
 311     protected void dumpOne(PrintStream out, CONTROL obj, String prefix) {
 312         Map<String, Object> data = getWrapper().wrap(getControlClass(), getControlClass().cast(obj)).getPropertiesQiuet();
 313         out.println(prefix + "+-" + buildClassChain(obj.getClass()));
 314         for (String key : data.keySet()) {
 315             out.print(prefix + PREFIX_DELTA + "  " + key + "=");
 316             if (data.get(key) == null) {
 317                 out.println("null");
 318             } else {
 319                 out.println(data.get(key));
 320             }
 321         }
 322     }
 323 
 324     /**
 325      *
 326      * @param out
 327      * @param lookup
 328      */
 329     protected abstract void dump(PrintStream out, Lookup<? extends CONTROL> lookup);
 330 
 331     public void dump(PrintStream out) {
 332         dump(out, this);
 333     }
 334     /*
 335     static class LookupImpl<T> extends AbstractLookup<T> {
 336 
 337     AbstractLookup<T> parent;
 338 
 339     public LookupImpl(Environment env, AbstractLookup<T> parent, Class<T> clss, LookupCriteria<T> criteria) {
 340     super(env, clss, criteria);
 341     this.parent = parent;
 342     }
 343 
 344     @Override
 345     public List<T> getChildren(T subParent) {
 346     return getFound();
 347     }
 348 




  24  */
  25 package org.jemmy.lookup;
  26 
  27 import java.io.PrintStream;
  28 import java.util.List;
  29 import org.jemmy.interfaces.*;
  30 import java.util.ArrayList;
  31 import java.util.HashMap;
  32 import java.util.Map;
  33 import org.jemmy.control.Wrap;
  34 import org.jemmy.control.Wrapper;
  35 import org.jemmy.env.Environment;
  36 import org.jemmy.env.TestOut;
  37 import org.jemmy.timing.State;
  38 
  39 /**
  40  * Default implementation of Lookup. Regularly, it is enough just override this
  41  * implementation and allow it to handle sub-lookups creation.
  42  * @see AbstractLookup#lookup(org.jemmy.lookup.LookupCriteria)
  43  * @see AbstractLookup#lookup(java.lang.Class, org.jemmy.lookup.LookupCriteria)
  44  * @param <CONTROL> todo document
  45  * @author shura
  46  */
  47 public abstract class AbstractLookup<CONTROL> extends AbstractParent<CONTROL> implements Lookup<CONTROL> {
  48 
  49     static final String PREFIX_DELTA = "| ";
  50     private ArrayList<CONTROL> found;
  51     Environment env;
  52     private Class<CONTROL> clss;
  53     private LookupCriteria<CONTROL> criteria = null;
  54     private Wrapper wrapper;
  55 
  56     /**
  57      * Identifies output where lookup progress is printed.
  58      * @see Environment#getOutput(java.lang.String)
  59      * @see AbstractLookup#wait(int)
  60      * @see AbstractLookup#size()
  61      */
  62     public static final String OUTPUT = AbstractLookup.class.getName() + ".OUTPUT";
  63 
  64 
  65     static {
  66         Environment.getEnvironment().initTimeout(WAIT_CONTROL_TIMEOUT);
  67         Environment.getEnvironment().initOutput(OUTPUT, TestOut.getNullOutput());
  68     }
  69 
  70     /**
  71      * This actual lookup logic is delegated to <code>getCildren(java.lang.Object)</code>
  72      * method
  73      * @see AbstractLookup#getChildren(java.lang.Object)
  74      * @param env todo document
  75      * @param controlClass todo document
  76      * @param criteria todo document
  77      * @param wrapper todo document
  78      */
  79     public AbstractLookup(Environment env, Class<CONTROL> controlClass, LookupCriteria<CONTROL> criteria, Wrapper wrapper) {
  80         this.env = env;
  81         found = new ArrayList<CONTROL>();
  82         this.clss = controlClass;
  83         this.criteria = criteria;
  84         this.wrapper = wrapper;
  85     }
  86 
  87     Wrapper getWrapper() {
  88         return wrapper;
  89     }
  90 




  91     LookupCriteria<CONTROL> getCriteria() {
  92         return criteria;
  93     }
  94 




  95     Environment getEnvironment() {
  96         return env;
  97     }
  98 
  99     /**

 100      * @return The class of the sount controls.
 101      */
 102     Class<CONTROL> getControlClass() {
 103         return clss;
 104     }
 105 
 106     public <T extends CONTROL> Lookup<T> lookup(Class<T> controlClass, LookupCriteria<T> criteria) {
 107         return new ClassLookupImpl<CONTROL, T>(env, this, controlClass, criteria, wrapper);
 108     }
 109 
 110     public Lookup<CONTROL> lookup(LookupCriteria<CONTROL> criteria) {
 111         return new ClassLookupImpl<CONTROL, CONTROL>(env, this, clss, criteria, wrapper);
 112     }
 113 
 114     /**
 115      * Waits for certain number of controls to fit criteria.
 116      * Depending on how outputs set, prints out info about the lookup.
 117      * @param count todo document
 118      * @return this, after the count of found number of found controls
 119      * exceeds the required.
 120      * @see AbstractLookup#OUTPUT
 121      */
 122     public Lookup<? extends CONTROL> wait(final int count) {
 123         getEnvironment().getOutput(OUTPUT).println("Waiting for " + count + " controls of " + clss.getName() + " class fitting criteria " + criteria);
 124         env.getWaiter(Lookup.WAIT_CONTROL_TIMEOUT.getName()).ensureState(new State<Integer>() {
 125 
 126             public Integer reached() {
 127                 if(found.size() < count)
 128                     refresh();
 129                 return (found.size() >= count) ? found.size() : null;
 130             }
 131 
 132             @Override
 133             public String toString() {
 134                 return "Waiting for " + count + " " + clss.getName() + " controls to be found adhering to "
 135                         + criteria;
 136             }
 137 
 138         });
 139         return this;
 140     }
 141 
 142     /**
 143      * Gets the number of controls which fit criteria.
 144      * Depending on how outputs set, prints out info about the lookup.
 145      * @see AbstractLookup#OUTPUT
 146      * @return todo document
 147      */
 148     public int size() {
 149         getEnvironment().getOutput(OUTPUT).println("Getting number of controls of " + clss.getName() + " class fitting criteria " + criteria);
 150         refresh();
 151         return found.size();
 152     }
 153 



 154     void refresh() {
 155         found.clear();
 156         List childen = getChildren(null);
 157         if (childen != null) {
 158             for (Object c : childen) {
 159                 add(c);
 160             }
 161         }
 162     }
 163 
 164     @SuppressWarnings("element-type-mismatch")
 165     private void add(Object subparent) {
 166         if (subparent != null/* && !found.contains(subparent)*/) {
 167             if (clss.isInstance(subparent) && check(clss.cast(subparent))) {
 168                 found.add(clss.cast(subparent));
 169             }
 170             List childen = getChildren(subparent);
 171             if (childen != null) {
 172                 for (Object child : childen) {
 173                     add(child);
 174                 }
 175             }
 176         }
 177     }
 178 





 179     protected boolean check(CONTROL control) {
 180         return control != null && criteria.check(control);
 181     }
 182 
 183     /**
 184      * Returns Wrap of the control with specified index
 185      * @param index todo document
 186      * @return Wrap
 187      */
 188     public Wrap<? extends CONTROL> wrap(int index) {
 189         return instantiate(get(index));
 190     }
 191 




 192     public Wrap<? extends CONTROL> wrap() {
 193         return wrap(0);
 194     }
 195 
 196     /**
 197      * {@inheritDoc}
 198      */
 199     public <INTERFACE extends ControlInterface> INTERFACE as(int index, Class<INTERFACE> interfaceClass) {
 200         return wrap(index).as(interfaceClass);
 201     }
 202 
 203     /**
 204      * {@inheritDoc}
 205      */
 206     public <INTERFACE extends ControlInterface> INTERFACE as(Class<INTERFACE> interfaceClass) {
 207         return as(0, interfaceClass);
 208     }
 209 
 210     /**
 211      * {@inheritDoc}
 212      */
 213     public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> INTERFACE as(int index, Class<INTERFACE> interfaceClass, Class<TYPE> type) {
 214         return wrap(index).as(interfaceClass, type);
 215     }
 216 
 217     /**
 218      * {@inheritDoc}
 219      */
 220     public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> INTERFACE as(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
 221         return as(0, interfaceClass, type);
 222     }
 223 
 224     public CONTROL get(int index) {
 225         wait(index + 1);
 226         return found.get(index);
 227     }
 228 
 229     /**
 230      * {@inheritDoc}
 231      */
 232     public CONTROL get() {
 233         return get(0);
 234     }
 235 




 236     List<CONTROL> getFound() {
 237         return found;
 238     }
 239 




 240     public Class<CONTROL> getType() {
 241         return getControlClass();
 242     }
 243 
 244     /**
 245      * Override this to get subchildren of the controls in the hierarchy.
 246      * List could contain any type of objects - not just <code>CONTROL</code>.
 247      * @param subParent - one of the elements in the hierarchy reflected by this lookup.
 248      * If null passed - first level children are expected.
 249      * @return todo document
 250      */
 251     abstract List getChildren(Object subParent);
 252 
 253     private String buildClassChain(Class cls) {
 254         StringBuilder sb = new StringBuilder(cls.getName());
 255         if (getType().isInterface()) {
 256             sb.append(" implements ").append(getType().getName());
 257         } else {
 258             do {
 259                 cls = cls.getSuperclass();
 260                 sb.append(" <- ").append(cls.getName());
 261             } while (!cls.equals(getType()) && !cls.equals(Object.class));
 262         }
 263         return sb.toString();
 264     }
 265 
 266     /**
 267      * Wraps the control with a <code>Wrap</code> class.
 268      * @see Wrap
 269      * @param control todo document
 270      * @return Wrap
 271      */
 272     private Wrap<? extends CONTROL> instantiate(CONTROL control) {
 273         return wrapper.wrap(clss, control);
 274     }
 275 






 276     protected void dumpOne(PrintStream out, CONTROL obj, String prefix) {
 277         Map<String, Object> data = getWrapper().wrap(getControlClass(), getControlClass().cast(obj)).getPropertiesQiuet();
 278         out.println(prefix + "+-" + buildClassChain(obj.getClass()));
 279         for (String key : data.keySet()) {
 280             out.print(prefix + PREFIX_DELTA + "  " + key + "=");
 281             if (data.get(key) == null) {
 282                 out.println("null");
 283             } else {
 284                 out.println(data.get(key));
 285             }
 286         }
 287     }
 288 





 289     protected abstract void dump(PrintStream out, Lookup<? extends CONTROL> lookup);
 290 
 291     public void dump(PrintStream out) {
 292         dump(out, this);
 293     }
 294     /*
 295     static class LookupImpl<T> extends AbstractLookup<T> {
 296 
 297     AbstractLookup<T> parent;
 298 
 299     public LookupImpl(Environment env, AbstractLookup<T> parent, Class<T> clss, LookupCriteria<T> criteria) {
 300     super(env, clss, criteria);
 301     this.parent = parent;
 302     }
 303 
 304     @Override
 305     public List<T> getChildren(T subParent) {
 306     return getFound();
 307     }
 308 


< prev index next >