All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jemmy.lookup.AbstractLookup Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2007, 2017 Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation. Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package org.jemmy.lookup;

import java.io.PrintStream;
import java.util.List;
import org.jemmy.interfaces.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.jemmy.control.Wrap;
import org.jemmy.control.Wrapper;
import org.jemmy.env.Environment;
import org.jemmy.env.TestOut;
import org.jemmy.timing.State;

/**
 * Default implementation of Lookup. Regularly, it is enough just override this
 * implementation and allow it to handle sub-lookups creation.
 * @see AbstractLookup#lookup(org.jemmy.lookup.LookupCriteria)
 * @see AbstractLookup#lookup(java.lang.Class, org.jemmy.lookup.LookupCriteria)
 * @param  todo document
 * @author shura
 */
public abstract class AbstractLookup extends AbstractParent implements Lookup {

    static final String PREFIX_DELTA = "| ";
    private ArrayList found;
    Environment env;
    private Class clss;
    private LookupCriteria criteria = null;
    private Wrapper wrapper;

    /**
     * Identifies output where lookup progress is printed.
     * @see Environment#getOutput(java.lang.String)
     * @see AbstractLookup#wait(int)
     * @see AbstractLookup#size()
     */
    public static final String OUTPUT = AbstractLookup.class.getName() + ".OUTPUT";


    static {
        Environment.getEnvironment().initTimeout(WAIT_CONTROL_TIMEOUT);
        Environment.getEnvironment().initOutput(OUTPUT, TestOut.getNullOutput());
    }

    /**
     * This actual lookup logic is delegated to getCildren(java.lang.Object)
     * method
     * @see AbstractLookup#getChildren(java.lang.Object)
     * @param env todo document
     * @param controlClass todo document
     * @param criteria todo document
     * @param wrapper todo document
     */
    public AbstractLookup(Environment env, Class controlClass, LookupCriteria criteria, Wrapper wrapper) {
        this.env = env;
        found = new ArrayList();
        this.clss = controlClass;
        this.criteria = criteria;
        this.wrapper = wrapper;
    }

    Wrapper getWrapper() {
        return wrapper;
    }

    LookupCriteria getCriteria() {
        return criteria;
    }

    Environment getEnvironment() {
        return env;
    }

    /**
     * @return The class of the sount controls.
     */
    Class getControlClass() {
        return clss;
    }

    public  Lookup lookup(Class controlClass, LookupCriteria criteria) {
        return new ClassLookupImpl(env, this, controlClass, criteria, wrapper);
    }

    public Lookup lookup(LookupCriteria criteria) {
        return new ClassLookupImpl(env, this, clss, criteria, wrapper);
    }

    /**
     * Waits for certain number of controls to fit criteria.
     * Depending on how outputs set, prints out info about the lookup.
     * @param count todo document
     * @return this, after the count of found number of found controls
     * exceeds the required.
     * @see AbstractLookup#OUTPUT
     */
    public Lookup wait(final int count) {
        getEnvironment().getOutput(OUTPUT).println("Waiting for " + count + " controls of " + clss.getName() + " class fitting criteria " + criteria);
        env.getWaiter(Lookup.WAIT_CONTROL_TIMEOUT.getName()).ensureState(new State() {

            public Integer reached() {
                if(found.size() < count)
                    refresh();
                return (found.size() >= count) ? found.size() : null;
            }

            @Override
            public String toString() {
                return "Waiting for " + count + " " + clss.getName() + " controls to be found adhering to "
                        + criteria;
            }

        });
        return this;
    }

    /**
     * Gets the number of controls which fit criteria.
     * Depending on how outputs set, prints out info about the lookup.
     * @see AbstractLookup#OUTPUT
     * @return todo document
     */
    public int size() {
        getEnvironment().getOutput(OUTPUT).println("Getting number of controls of " + clss.getName() + " class fitting criteria " + criteria);
        refresh();
        return found.size();
    }

    void refresh() {
        found.clear();
        List childen = getChildren(null);
        if (childen != null) {
            for (Object c : childen) {
                add(c);
            }
        }
    }

    @SuppressWarnings("element-type-mismatch")
    private void add(Object subparent) {
        if (subparent != null/* && !found.contains(subparent)*/) {
            if (clss.isInstance(subparent) && check(clss.cast(subparent))) {
                found.add(clss.cast(subparent));
            }
            List childen = getChildren(subparent);
            if (childen != null) {
                for (Object child : childen) {
                    add(child);
                }
            }
        }
    }

    protected boolean check(CONTROL control) {
        return control != null && criteria.check(control);
    }

    /**
     * Returns Wrap of the control with specified index
     * @param index todo document
     * @return Wrap
     */
    public Wrap wrap(int index) {
        return instantiate(get(index));
    }

    public Wrap wrap() {
        return wrap(0);
    }

    /**
     * {@inheritDoc}
     */
    public  INTERFACE as(int index, Class interfaceClass) {
        return wrap(index).as(interfaceClass);
    }

    /**
     * {@inheritDoc}
     */
    public  INTERFACE as(Class interfaceClass) {
        return as(0, interfaceClass);
    }

    /**
     * {@inheritDoc}
     */
    public > INTERFACE as(int index, Class interfaceClass, Class type) {
        return wrap(index).as(interfaceClass, type);
    }

    /**
     * {@inheritDoc}
     */
    public > INTERFACE as(Class interfaceClass, Class type) {
        return as(0, interfaceClass, type);
    }

    public CONTROL get(int index) {
        wait(index + 1);
        return found.get(index);
    }

    /**
     * {@inheritDoc}
     */
    public CONTROL get() {
        return get(0);
    }

    List getFound() {
        return found;
    }

    public Class getType() {
        return getControlClass();
    }

    /**
     * Override this to get subchildren of the controls in the hierarchy.
     * List could contain any type of objects - not just CONTROL.
     * @param subParent - one of the elements in the hierarchy reflected by this lookup.
     * If null passed - first level children are expected.
     * @return todo document
     */
    abstract List getChildren(Object subParent);

    private String buildClassChain(Class cls) {
        StringBuilder sb = new StringBuilder(cls.getName());
        if (getType().isInterface()) {
            sb.append(" implements ").append(getType().getName());
        } else {
            do {
                cls = cls.getSuperclass();
                sb.append(" <- ").append(cls.getName());
            } while (!cls.equals(getType()) && !cls.equals(Object.class));
        }
        return sb.toString();
    }

    /**
     * Wraps the control with a Wrap class.
     * @see Wrap
     * @param control todo document
     * @return Wrap
     */
    private Wrap instantiate(CONTROL control) {
        return wrapper.wrap(clss, control);
    }

    protected void dumpOne(PrintStream out, CONTROL obj, String prefix) {
        Map data = getWrapper().wrap(getControlClass(), getControlClass().cast(obj)).getPropertiesQiuet();
        out.println(prefix + "+-" + buildClassChain(obj.getClass()));
        for (String key : data.keySet()) {
            out.print(prefix + PREFIX_DELTA + "  " + key + "=");
            if (data.get(key) == null) {
                out.println("null");
            } else {
                out.println(data.get(key));
            }
        }
    }

    protected abstract void dump(PrintStream out, Lookup lookup);

    public void dump(PrintStream out) {
        dump(out, this);
    }
    /*
    static class LookupImpl extends AbstractLookup {

    AbstractLookup parent;

    public LookupImpl(Environment env, AbstractLookup parent, Class clss, LookupCriteria criteria) {
    super(env, clss, criteria);
    this.parent = parent;
    }

    @Override
    public List getChildren(T subParent) {
    return getFound();
    }

    @Override
    public Wrap instantiate(T control) {
    return parent.instantiate(control);
    }

    @Override
    protected void refresh() {
    parent.refresh();
    super.refresh();
    }

    }
     */

    static class ClassLookupImpl extends AbstractLookup {

        AbstractLookup parent;
        Class cls;

        public ClassLookupImpl(Environment env, AbstractLookup parent, Class cls, LookupCriteria criteria, Wrapper wrapper) {
            super(env, cls, criteria, wrapper);
            this.cls = cls;
            this.parent = parent;
        }

        @Override
        protected boolean check(ST control) {
            return getControlClass().isInstance(control) && super.check(control);
        }

        @Override
        public List getChildren(Object subParent) {
            return getFound();
        }

        @Override
        protected void refresh() {
            parent.refresh();
            for (T next : parent.found) {
                if (cls.isInstance(next) && check(cls.cast(next))) {
                    super.found.add(cls.cast(next));
                }
            }
        }

        @Override
        protected void dump(PrintStream out, Lookup lookup) {
            parent.dump(out, lookup);
        }
    }
    /*
    static class ClassLookupImpl extends AbstractLookup {

    AbstractLookup parent;

    public ClassLookupImpl(Environment env, AbstractLookup parent, Class cls, LookupCriteria criteria) {
    super(env, cls, criteria);
    this.parent = parent;
    }

    @Override
    protected boolean check(ST wrap) {
    return getControlClass().isInstance(wrap) && super.check(wrap);
    }

    @Override
    public List getChildren(Object subParent) {
    return getFound();
    }

    @Override
    public Wrap instantiate(ST wrap) {
    return parent.instantiate(wrap);
    }

    @Override
    protected void refresh() {
    parent.refresh();
    super.refresh();
    }

    }
     */
    /*
    class ClassParent implements Parent {

    Class clss;

    ClassParent(Class clss) {
    this.clss = clss;
    }

    public Wrap instantiate(T wrap) {
    return (Wrap) AbstractLookup.this.instantiate((CONTROL) wrap);
    }

    public Lookup lookup(final LookupCriteria criteria) {
    return new LookupImpl(env, this, new TypedLookup(clss) {

    @Override
    public boolean checkControl(T wrap) {
    return criteria.check(wrap);
    }
    });
    }
    }
     */
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy