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

org.jemmy.control.Wrap 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.control;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.jemmy.JemmyException;
import org.jemmy.Point;
import org.jemmy.Rectangle;
import org.jemmy.TimeoutExpiredException;
import org.jemmy.action.GetAction;
import org.jemmy.env.Environment;
import org.jemmy.env.TestOut;
import org.jemmy.env.Timeout;
import org.jemmy.image.Image;
import org.jemmy.interfaces.*;
import org.jemmy.timing.State;

/**
 * This is a wrap which holds reference to a control without UI hierarchy. It
 * also encapsulates all the logic to deal with the underlying control, in terms
 * of implementations of ControlInterface.
 *
 * @see Wrap#as(java.lang.Class)
 * @see Wrap#is(java.lang.Class)
 * @param  type of the encapsulated object.
 * @author shura, erikgreijus
 */
@ControlType(Object.class)
@ControlInterfaces({Mouse.class, Keyboard.class, Drag.class})
public abstract class Wrap {

    public static final String BOUNDS_PROP_NAME = "bounds";
    public static final String CLICKPOINT_PROP_NAME = "clickPoint";
    public static final String CONTROL_CLASS_PROP_NAME = "control.class";
    public static final String CONTROL_PROP_NAME = "control";
    public static final String INPUT_FACTORY_PROPERTY = "input.control.interface.factory";
    public static final String IMAGE_LOADER_PROPERTY = "image.loader";
    public static final String IMAGE_CAPTURER_PROPERTY = "image.capturer";
    public static final String TEXT_PROP_NAME = "text";
    public static final String POSITION_PROP_NAME = "position";
    public static final String VALUE_PROP_NAME = "value";
    public static final String WRAPPER_CLASS_PROP_NAME = "wrapper.class";
    public static final String TOOLTIP_PROP_NAME = "tooltip";
    public static final String NAME_PROP_NAME = "name";
    public static final Timeout WAIT_STATE_TIMEOUT = new Timeout("wait.state", 1000);

    public static final String OUTPUT = Wrap.class.getName() + ".OUTPUT";
    private static DefaultWrapper theWrapper = new DefaultWrapper(Environment.getEnvironment());

    static {
        Environment.getEnvironment().initTimeout(WAIT_STATE_TIMEOUT);
        Environment.getEnvironment().initOutput(OUTPUT, TestOut.getNullOutput());
        Environment.getEnvironment().initTimeout(Mouse.CLICK);
        Environment.getEnvironment().initTimeout(Drag.BEFORE_DRAG_TIMEOUT);
        Environment.getEnvironment().initTimeout(Drag.BEFORE_DROP_TIMEOUT);
        Environment.getEnvironment().initTimeout(Drag.IN_DRAG_TIMEOUT);
        Environment.getEnvironment().initTimeout(Keyboard.PUSH);
    }

    public static DefaultWrapper getWrapper() {
        return theWrapper;
    }
    CONTROL node;
    Environment env;

    /**
     * Fur null source.
     *
     * @see org.jemmy.env.Environment
     * @param env The environment
     */
    protected Wrap(Environment env) {
        this.env = env;
        node = null;
        fillTheProps(false);
    }

    /**
     *
     * @see org.jemmy.env.Environment
     * @param env The environment
     * @param node The encapsulated object
     */
    protected Wrap(Environment env, CONTROL node) {
        this.env = env;
        this.node = node;
    }

    /**
     *
     * @see org.jemmy.env.Environment
     * @return environment instance used by this
     */
    public Environment getEnvironment() {
        return env;
    }

    public void setEnvironment(Environment env) {
        this.env = env;
    }

    /**
     *
     * @return The encapsulated object
     */
    @Property(CONTROL_PROP_NAME)
    public CONTROL getControl() {
        return node;
    }

    /**
     * Return default point to click, drag. This implementation returns the
     * center must be overriden if something different is desired.
     *
     * @return the default click point
     */
    @Property(CLICKPOINT_PROP_NAME)
    public Point getClickPoint() {
        return new Point(getScreenBounds().width / 2, (getScreenBounds().height / 2));
    }

    /**
     * Returns control bounds in screen coordinates. These bounds could include
     * parts that are covered by other controls or clipped out by parent
     * components. If the control is not shown {@linkplain
     * JemmyException JemmyException} will be thrown.
     *
     * @return control bounds in screen coordinates.
     * @throws JemmyException if the control is not visible
     */
    @Property(BOUNDS_PROP_NAME)
    public abstract Rectangle getScreenBounds();

    /**
     * Transforms point in local control coordinate system to screen
     * coordinates.
     *
     * @param local the local coordinate
     * @return a absolute translated point
     * @see #toLocal(org.jemmy.Point)
     */
    public Point toAbsolute(Point local) {
        Rectangle bounds = getScreenBounds();
        return local.translate(bounds.x, bounds.y);
    }

    /**
     * Transforms point in screen coordinates to local control coordinate
     * system.
     *
     * @param local the local coordinate
     * @return coordinates which should be used for mouse operations.
     * @see #toAbsolute(org.jemmy.Point)
     */
    public Point toLocal(Point local) {
        Rectangle bounds = getScreenBounds();
        return local.translate(-bounds.x, -bounds.y);
    }

    /**
     * Captures the screen area held by the component. ImageFactory performs the
     * actual capturing.
     *
     * @return TODO find a replacement
     */
    public Image getScreenImage() {
        Rectangle bounds = getScreenBounds();
        return getScreenImage(new Rectangle(0, 0, bounds.width, bounds.height));
    }

    /**
     * Captures portion of the screen area held by the component. ImageFactory
     * performs the actual capturing.
     *
     * @param rect Part of the control to capture
     * @return TODO find a replacement
     */
    public Image getScreenImage(Rectangle rect) {
        if (getEnvironment().getImageCapturer() == null) {
            throw new JemmyException("Image capturer is not specified.");
        }
        return getEnvironment().getImageCapturer().capture(this, rect);
    }

    /**
     * Waits for a portion of image to be exact the same as the parameter.
     *
     * @see Wrap#as(java.lang.Class)
     * @param golden the image to match against
     * @param rect A portion of control to compare.
     * @param resID ID of a result image to save in case of failure. No image
     * saved if null.
     * @param diffID ID of a diff image to save in case of failure. No image
     * saved if null.
     */
    public void waitImage(final Image golden, final Rectangle rect, String resID, String diffID) {
        try {
            waitState(new State() {

                public Object reached() {
                    return (getScreenImage(rect).compareTo(golden) == null) ? true : null;
                }

                @Override
                public String toString() {
                    return "Control having expected image";
                }
            });
        } catch (TimeoutExpiredException e) {
            if (diffID != null) {
                getEnvironment().getOutput(OUTPUT).println("Saving difference to " + diffID);
                getScreenImage(rect).compareTo(golden).save(diffID);
            }
            throw e;
        } finally {
            if (resID != null) {
                getEnvironment().getOutput(OUTPUT).println("Saving result to " + resID);
                getScreenImage(rect).save(resID);
            }
        }
    }

    /**
     * Waits for image to be exact the same as the parameter.
     *
     * @see Wrap#as(java.lang.Class)
     * @param golden the image to match against
     * @param resID ID of a result image to save in case of failure. No image
     * saved if null.
     * @param diffID ID of a diff image to save in case of failure. No image
     * saved if null.
     */
    public void waitImage(final Image golden, String resID, String diffID) {
        Rectangle bounds = getScreenBounds();
        waitImage(golden, new Rectangle(0, 0, bounds.width, bounds.height), resID, diffID);
    }

    /**
     * TODO javadoc
     *
     * @param  the states type
     * @param state the state
     * @param value the state value
     * @return last returned State value
     * @throws TimeoutExpiredException in case the wait is unsuccessful.
     */
    public  V waitState(State state, V value) {
        return getEnvironment().getWaiter(WAIT_STATE_TIMEOUT).ensureValue(value, state);
    }

    /**
     * @param  the states type
     * @param state the state
     * @return last returned State value
     * @throws TimeoutExpiredException in case the wait is unsuccessful.
     */
    public  V waitState(State state) {
        return getEnvironment().getWaiter(WAIT_STATE_TIMEOUT).ensureState(state);
    }

    /**
     * ***********************************************************************
     */
    /*
     * INTERFACES
     */
    /**
     * ***********************************************************************
     */
    private Method findAsMethod(Class interfaceClass, Class type) {
        while (type != null) {
            for (Method m : getClass().getMethods()) {
                As as = m.getAnnotation(As.class);
                Class returnType = m.getReturnType();
                if (as != null && interfaceClass.isAssignableFrom(returnType) && as.value().equals(type)) {
                    if (m.getParameterTypes().length > 0 && type.equals(Void.class)
                            || m.getParameterTypes().length > 1 && !type.equals(Void.class)) {
                        throw new IllegalStateException("wrong number of parameters in an @As method");
                    }
                    return m;
                }
            }
            type = type.getSuperclass();
        }
        return null;
    }

    /**
     * Checks if the control could be treated as a ControlInterface. If it is,
     * Wrap#as(java.lang.Class) will be called. This implementation
     * checks whether the class implements the necessary interface. It also
     * works for root interfaces such as
     * MouseTarget and
     * KeyTarget, which implementations are encapsulated. If some
     * other functionality is desired, must be overriden together with
     * as(java.lang.Class)
     *
     * @see Wrap#is(java.lang.Class)
     * @param  the control interface
     * @param interfaceClass the interface class
     * @return true if the control is an ControlInterface,
     *         false otherwise
     */
    public  boolean is(Class interfaceClass) {
        if (interfaceClass.isInstance(this)) {
            return true;
        }
        return findAsMethod(interfaceClass, Void.class) != null;
    }

    /**
     * Checks if the control could be treated as a parametrized
     * ControlInterface. If it is,
     * Wrap#as(java.lang.Class, java.lang.Class) will be called.
     * This implementation checks whether the class implements the necessary
     * interface. It also works for root interfaces such as
     * MouseTarget and
     * KeyTarget, which implementations are encapsulated. If some
     * other functionality is desired, must be overriden together with
     * as(java.lang.Class)
     *
     * @see Wrap#is(java.lang.Class)
     * @param  the type interface
     * @param  the control interface
     * @param interfaceClass the interface class
     * @param type The parameter class.
     * @return true if the control is an ControlInterface,
     *         false otherwise
     */
    public > boolean is(Class interfaceClass, Class type) {
        if (interfaceClass.isInstance(this)) {
            if (interfaceClass.cast(this).getType().isAssignableFrom(type)) {
                return true;
            }
        }
        return findAsMethod(interfaceClass, type) != null;
    }

    private Object callAsMethod(Class interfaceClass, Class type) {
        Method m = findAsMethod(interfaceClass, type);
        if (m != null) {
            try {
                if (m.getParameterTypes().length == 0) {
                    return m.invoke(this);
                } else if (m.getParameterTypes().length == 1) {
                    return m.invoke(this, !type.equals(Void.class) ? type : Object.class);
                } else {
                    throw new InterfaceException(this, interfaceClass);
                }
            } catch (IllegalAccessException ex) {
                throw new JemmyException("Unable to call method \"" + m.getName() + "()\"", ex, this);
            } catch (IllegalArgumentException ex) {
                throw new JemmyException("Unable to call method \"" + m.getName() + "()\"", ex, this);
            } catch (InvocationTargetException ex) {
                throw new JemmyException("Unable to call method \"" + m.getName() + "()\"", ex, this);
            }
        }
        return null;
    }

    /**
     * Returns an implementation of interface associated with this object. First
     * it checks
     *
     * @see Wrap#is(java.lang.Class)
     * @param  the control interface
     * @param interfaceClass the interface class
     * @return the control interface instance
     */
    public  INTERFACE as(Class interfaceClass) {
        if (interfaceClass.isInstance(this)) {
            return interfaceClass.cast(this);
        }

        Object res = callAsMethod(interfaceClass, Void.class);
        if (res != null) {
            return (INTERFACE) res;
        }

        throw new InterfaceException(this, interfaceClass);
    }

    /**
     * Returns an implementation of interface associated with the object.
     *
     * @see Wrap#is(java.lang.Class)
     * @param  the type interface
     * @param  the control interface
     * @param interfaceClass the interface class
     * @param type The parameter class.
     * @return the type control instance
     */
    public > INTERFACE as(Class interfaceClass, Class type) {
        if (interfaceClass.isInstance(this)) {
            if (interfaceClass.cast(this).getType().isAssignableFrom(type)) {
                return interfaceClass.cast(this);
            }
        }

        Object res = callAsMethod(interfaceClass, type);
        if (res != null) {
            return (INTERFACE) res;
        }

        throw new InterfaceException(this, interfaceClass);
    }
    /**
     * ***********************************************************************
     */
    /*
     * INPUT
     */
    /**
     * ***********************************************************************
     */
    private Mouse mouse = null;
    private Drag drag = null;
    private Keyboard keyboard = null;

    /**
     * A shortcut to as(MouseTarget.class).mouse()
     *
     * @return the mouse target
     */
    @As(Mouse.class)
    public Mouse mouse() {
        if (mouse == null) {
            mouse = getEnvironment().getInputFactory().create(this, Mouse.class);
        }
        return mouse;
    }

    /**
     * A shortcut to as(MouseTarget.class).drag()
     *
     * @return the drag target
     */
    @As(Drag.class)
    public Drag drag() {
        if (drag == null) {
            drag = getEnvironment().getInputFactory().create(this, Drag.class);
        }
        return drag;
    }

    /**
     * A shortcut to as(KeyTarget.class).wrap()
     *
     * @return the wrap target
     */
    @As(Keyboard.class)
    public Keyboard keyboard() {
        if (keyboard == null) {
            keyboard = getEnvironment().getInputFactory().create(this, Keyboard.class);
        }
        return keyboard;
    }
    /**
     * ***********************************************************************
     */
    /*
     * PROPERTIES
     */
    /**
     * ***********************************************************************
     */
    private HashMap properties = new HashMap();

    @Property(CONTROL_CLASS_PROP_NAME)
    public Class getControlClass() {
        return getControl().getClass();
    }

    private void fillTheProps(boolean quiet) {
        properties.clear();
        properties.put(WRAPPER_CLASS_PROP_NAME, getClass());
        readAnnotationProps(quiet);
        readControlProps(quiet);
    }

    private void readControlProps(boolean quiet) {
        Class cls = getClass();
        do {
            if (cls.isAnnotationPresent(FieldProperties.class)) {
                for (String s : cls.getAnnotation(FieldProperties.class).value()) {
                    Object value;
                    try {
                        value = getFieldProperty(s);
                    } catch (Exception e) {
                        getEnvironment().getOutput().printStackTrace(e);
                        value = e.toString();
                        if (!(e instanceof JemmyException) && !quiet) {
                            throw new JemmyException("Exception while getting property \"" + s + "\"", e);
                        }
                    }
                    properties.put(s, value);
                }
            }
            if (cls.isAnnotationPresent(MethodProperties.class)) {
                for (String s : cls.getAnnotation(MethodProperties.class).value()) {
                    Object value;
                    try {
                        value = getMethodProperty(s);
                    } catch (Exception e) {
                        getEnvironment().getOutput().printStackTrace(e);
                        value = e.toString();
                        if (!(e instanceof JemmyException) && !quiet) {
                            throw new JemmyException("Exception while getting property \"" + s + "\"", e);
                        }
                    }
                    properties.put(s, value);
                }
            }
        } while ((cls = cls.getSuperclass()) != null);
    }

    private void addAnnotationProps(Class cls, boolean quiet) {
        for (Method m : cls.getMethods()) {
            if (m.isAnnotationPresent(Property.class)) {
                String name = m.getAnnotation(Property.class).value();
                if (!properties.containsKey(name)) {
                    Object value;
                    try {
                        value = getProperty(this, m);
                    } catch (Exception e) {
                        if (quiet) {
                            getEnvironment().getOutput().printStackTrace(e);
                            value = e.toString();
                        } else {
                            throw new JemmyException("Exception while getting property \"" + name + "\"", e);
                        }
                    }
                    properties.put(name, value);
                }
            }
        }
    }

    private void readAnnotationProps(boolean quiet) {
        Class cls = getClass();
        do {
            addAnnotationProps(cls, quiet);
        } while ((cls = cls.getSuperclass()) != null);
        for (Class intf : getClass().getInterfaces()) {
            addAnnotationProps(intf, quiet);
        }
    }

    private void checkPropertyMethod(Method m) {
        if (m.getParameterTypes().length > 0) {
            throw new JemmyException("Method marked by @Property must not have parameters: "
                    + m.getDeclaringClass().getName() + "." + m.getName());
        }
    }

    private Method getPropertyMethod(Class cls, String name) {
        Class scls = cls;
        do {
            for (Method m : scls.getMethods()) {
                if (m.isAnnotationPresent(Property.class) && m.getAnnotation(Property.class).value().equals(name)) {
                    checkPropertyMethod(m);
                    return m;
                }
            }
        } while ((scls = scls.getSuperclass()) != null);
        for (Class intf : cls.getInterfaces()) {
            for (Method m : intf.getMethods()) {
                if (m.isAnnotationPresent(Property.class) && m.getAnnotation(Property.class).value().equals(name)) {
                    checkPropertyMethod(m);
                    return m;
                }
            }
        }
        return null;
    }

    private Object getProperty(Object object, Method m) {
        Property prop = m.getAnnotation(Property.class);
        try {
            return m.invoke(object);
        } catch (IllegalAccessException ex) {
            throw new JemmyException("Unable to obtain property \"" + ((prop != null) ? prop.value() : "null") + "\"", ex, this);
        } catch (IllegalArgumentException ex) {
            throw new JemmyException("Unable to obtain property \"" + ((prop != null) ? prop.value() : "null") + "\"", ex, this);
        } catch (InvocationTargetException ex) {
            throw new JemmyException("Unable to obtain property \"" + ((prop != null) ? prop.value() : "null") + "\"", ex, this);
        }
    }

    /**
     * Get property of the wrapped object. Uses first available from
     * 
    *
  1. methods annotated by org.jemmy.control.Property
  2. *
  3. wrapped object methods listed in org.jemmy.control.MethodProperties
  4. *
  5. wrapped object fields listed in org.jemmy.control.FieldProperties
  6. *
* * @param name property name * @throws JemmyException if no property found * @see Property * @see MethodProperties * @see FieldProperties * @return property value */ public Object getProperty(String name) { if (WRAPPER_CLASS_PROP_NAME.equals(name)) { return getClass(); } Method m = getPropertyMethod(this.getClass(), name); if (m != null) { return getProperty(this, m); } if (hasMethodProperty(name)) { return getMethodProperty(name); } if (hasFieldProperty(name)) { return getFieldProperty(name); } throw new JemmyException("No property \"" + name + "\"", this); } private Object getInterfaceProperty(Class cls, Object instance, String name) { Method m = getPropertyMethod(cls, name); if (m != null) { return getProperty(instance, m); } throw new JemmyException("No property \"" + name + "\" in interface " + cls.getName(), instance); } /** * Get property out of the control interface. Refer to the interface doc to * find out what properties are provided. * * @param the control interface * @param name the property name * @param intrfc the interface class * @return the control property */ public Object getProperty(String name, Class intrfc) { return getInterfaceProperty(intrfc, as(intrfc), name); } /** * Get property out of the control interface. Refer to the interface doc to * find out what properties are provided. * * @param the type interface * @param the control interface * @param name the property name * @param intrfc the interface class * @param type The parameter class. * @return the control property */ public > Object getProperty(String name, Class intrfc, Class type) { return getInterfaceProperty(intrfc, as(intrfc, type), name); } /** * Wait for the property * property to get the specified value. * WAIT_STATE_TIMOUT timeout is used * * @param property name of the property being waited for * @param value property value to wait */ public void waitProperty(final String property, final Object value) { getEnvironment().getWaiter(WAIT_STATE_TIMEOUT).ensureValue(value, new State() { public Object reached() { return getProperty(property); } @Override public String toString() { return "Control having property " + property + " expected value '" + value + "' (Property = '" + getProperty(property) + "')"; } }); } /** * Wait for the property * property of control interface to get the specified value. * WAIT_STATE_TIMOUT timeout is used * * @param the control interface * @param property the property name * @param intrfc the interface class * @param value the new parameter value */ public void waitProperty(final String property, final Class intrfc, final Object value) { Object instance = as(intrfc); getEnvironment().getWaiter(WAIT_STATE_TIMEOUT).ensureValue(value, new State() { public Object reached() { return getProperty(property, intrfc); } @Override public String toString() { return "Interface " + intrfc.getName() + " having property " + property + " expected value '" + value + "' (Property = '" + getProperty(property, intrfc) + "')"; } }); } /** * Wait for the property * property of control interface to get the specified value. * WAIT_STATE_TIMOUT timeout is used * * @param the type interface * @param the control interface * @param property the property name * @param intrfc the interface class * @param type the parameter class. * @param value the new parameter value */ public > void waitProperty(final String property, final Class intrfc, final Class type, final Object value) { getEnvironment().getWaiter(WAIT_STATE_TIMEOUT).ensureValue(value, new State() { public Object reached() { return getProperty(property, intrfc, type); } @Override public String toString() { return "Interface " + intrfc.getName() + " having property " + property + " expected value '" + value + "' (Property = '" + getProperty(property) + "')"; } }); } public boolean hasFieldProperty(String name) { Class cls = getClass(); do { if (cls.isAnnotationPresent(FieldProperties.class)) { FieldProperties props = cls.getAnnotation(FieldProperties.class); if (contains(props.value(), name)) { return true; } } } while ((cls = cls.getSuperclass()) != null); return false; } public boolean hasMethodProperty(String name) { Class cls = getClass(); do { if (cls.isAnnotationPresent(MethodProperties.class)) { MethodProperties props = cls.getAnnotation(MethodProperties.class); if (contains(props.value(), name)) { return true; } } } while ((cls = cls.getSuperclass()) != null); return false; } private boolean contains(String[] values, String name) { for (int i = 0; i < values.length; i++) { if (name.equals(values[i])) { return true; } } return false; } public Object getFieldProperty(final String name) { if (!hasFieldProperty(name)) { throw new JemmyException("No \"" + name + "\" field property specified on " + getClass().getName()); } GetAction action = new GetAction() { @Override public void run(Object... parameters) throws Exception { setResult(getControl().getClass().getField(name).get(getControl())); } }; Object result = action.dispatch(env); if (action.getThrowable() != null) { throw new JemmyException("Unable to obtain property \"" + name + "\"", action.getThrowable(), this); } return result; } public Object getMethodProperty(final String name) { if (!hasMethodProperty(name)) { throw new JemmyException("No \"" + name + "\" method property specified on " + getClass().getName()); } GetAction action = new GetAction() { @Override public void run(Object... parameters) throws Exception { setResult(getControl().getClass().getMethod(name).invoke(getControl())); } @Override public String toString() { return "Getting property \"" + name + "\" on " + getClass().getName(); } }; Object result = action.dispatch(env); if (action.getThrowable() != null) { throw new JemmyException("Unable to obtain property \"" + name + "\"", action.getThrowable(), this); } return result; } public

P getProperty(Class

valueClass, String name) { return valueClass.cast(getProperty(name)); } /** * Returns a a map of all known controls properties including values from * methods marked by * @Property and values of methods/field from * @MethodProperties/ * FieldProperties correspondingly. * * @return a map of properties * @throws RuntimeException should there be an exception thrown while * getting a property */ public HashMap getProperties() { fillTheProps(false); return properties; } /** * Returns a a map of all controls properties which is possible to obtain. * Similar to * getProperties() only exception is swallowed should there be * an exception thrown while getting a property. * * @return a map of properties which were possible to obtain. */ public HashMap getPropertiesQiuet() { fillTheProps(true); return properties; } }