com.smash.revolance.ui.model.element.api.Element.java Source code

Java tutorial

Introduction

Here is the source code for com.smash.revolance.ui.model.element.api.Element.java

Source

package com.smash.revolance.ui.model.element.api;

/*
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Revolance-UI-Model
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Copyright (C) 2012 - 2013 RevoLance
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program 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 for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

/*
    This file is part of Revolance.
    
    Revolance is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    Revolance 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 for more details.
    
    You should have received a copy of the GNU General Public License
    along with Revolance UI Suite.  If not, see <http://www.gnu.org/licenses/>.
*/

import com.smash.revolance.ui.model.bot.Bot;
import com.smash.revolance.ui.model.helper.BotHelper;
import com.smash.revolance.ui.model.helper.ImageHelper;
import com.smash.revolance.ui.model.helper.UserHelper;
import com.smash.revolance.ui.model.page.api.Page;
import com.smash.revolance.ui.model.page.api.PageBean;
import com.smash.revolance.ui.model.user.User;
import org.apache.log4j.Level;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.*;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.*;
import java.util.List;

/**
 * User: wsmash
 * Date: 26/01/13
 * Time: 23:59
 */
public class Element implements Comparable<Element> {
    private ElementBean bean = new ElementBean(this);
    private BufferedImage img;

    public Element() {

    }

    public Element(Page page, WebElement element) {
        this();
        setPage(page);
        setTag(element.getTagName());
        setDim(element.getSize());
        setPos(element.getLocation());
        setClz(element.getAttribute("class"));
        setId(element.getAttribute("id"));
    }

    public void setAlt(String alt) {
        this.bean.setAlt(alt);
    }

    public void setBackground(String img) {
        bean.setBg(img);
    }

    public static String getBg(String tag, WebElement element) {
        String bg = "";
        if (!tag.contentEquals("img")) {
            bg = element.getCssValue("background-image");
            if (bg.contentEquals("none")) {
                bg = element.getCssValue("background-url");
            }
        } else {
            bg = element.getAttribute("src");
        }
        if (bg == null || bg.contentEquals("none")) {
            bg = "";
        }
        if (!bg.isEmpty()) {
            //TODO: use standard image format instead of css/uri
            if (!bg.contains("url") && !bg.contains("http") && !bg.contains(ImageHelper.BASE64_IMAGE_PNG)) {
                bg = "";
            }
        }
        return bg;
    }

    public static Class<? extends Element> getImplementation(WebElement element) {
        String tag = element.getTagName();
        if (tag == null) {
            tag = "";
        }
        String type = element.getAttribute("type");
        if (type == null) {
            type = "";
        }
        String txt = element.getText();
        if (txt == null) {
            txt = "";
        }
        if (isALink(tag, txt)) {
            return Link.class;
        } else if (isAButton(tag, type)) {
            return Button.class;
        } else if (isAnInput(tag, type)) {
            return Input.class;
        } else if (isAData(tag, txt)) {
            return Data.class;
        } else if (isAnImage(element, tag)) {
            return Image.class;
        } else {
            return null;
        }
    }

    private static boolean isAnImage(WebElement element, String tag) {
        return !getBg(tag, element).isEmpty();
    }

    private static boolean isAData(String tag, String txt) {
        return !txt.trim().isEmpty() && (tag.contentEquals("li") || tag.contentEquals("p")
                || tag.contentEquals("label") || tag.startsWith("h"));
    }

    private static boolean isAnInput(String tag, String type) {
        return tag.contentEquals("input") && (!type.contentEquals("submit") && !type.contentEquals("button"));
    }

    private static boolean isAButton(String tag, String type) {
        return (tag.contentEquals("input") && (type.contentEquals("submit") || type.contentEquals("button")))
                || (tag.contentEquals("button"));
    }

    private static boolean isALink(String tag, String txt) {
        return tag.contentEquals("a") && !txt.isEmpty();
    }

    public Element(PageBean pageBean, ElementBean bean) {
        this.bean = bean;
        setPage(new Page(pageBean));
    }

    protected void setImplementation(String implementation) {
        this.bean.setImpl(implementation);
    }

    public boolean click() throws Exception {
        if (isClickable()) {
            UserHelper.browseTo(getUser(), getUrl());
            getBot().getUser().getLogger().log(Level.INFO, "Clicking on '" + getContent() + "'");

            try {
                _click(getBot());
                getBot().getUser().getLogger().log(Level.INFO, "Clicking on '" + getContent() + "' [Done]");
                setHref(getBot().getCurrentUrl());
                setClicked(true);
            } catch (Exception e) {
                setBroken(true);
                getBot().getUser().getLogger().log(Level.ERROR, "Clicking on '" + getContent() + "' [Failed]");
                getBot().getUser().getLogger().log(Level.ERROR, e);
            }
        }

        return hasBeenClicked();
    }

    private void _click(Bot bot) throws Exception {

        WebElement element = BotHelper.findMatchingElement(bot, this);
        if (element != null) {
            try {
                String disabled = element.getAttribute("disabled");
                if (disabled == null) {
                    element.click(); // Can thow an ex
                }
            } catch (UnhandledAlertException e) {
                UserHelper.handleAlert(getUser());
                _click(bot);
            }
        }
    }

    public boolean isIncluded(Element element) {
        return element.getBean().isIncluded(getBean());
    }

    public Rectangle getLocation() {
        return bean.getLocation();
    }

    //-- Beginning of setters / getters

    public void setId(String id) {
        bean.setId(id);
    }

    public String getId() {
        return bean.getId();
    }

    public String getHref() {
        if (!bean.isExternal()) {
            // The url is relative to the domain
            return getUser().getDomain() + bean.getHref();
        } else {
            return bean.getHref();
        }
    }

    public void setHref(String href) {
        if (href.startsWith(getUser().getDomain())) {
            // The url is relative to the domain
            href = href.substring(getUser().getDomain().length());
            bean.setHref(href);
        } else {
            // The url is absolute
            bean.setExternal(true);
            bean.setHref(href);
        }
    }

    public boolean hasBeenClicked() {
        return bean.hasBeenClicked();
    }

    public void setTag(String tag) {
        bean.setTag(tag);
    }

    public String getTag() {
        return bean.getTag();
    }

    public String getClz() {
        return bean.getClz();
    }

    public void setClz(String clz) {
        bean.setClz(clz);
    }

    public Dimension getDim() {
        return bean.getDim();
    }

    public void setDim(Dimension dim) {
        bean.setDim(dim);
    }

    public Point getPos() {
        return bean.getPos();
    }

    public void setPos(Point pos) {
        bean.setPos(pos);
    }

    public void setType(String type) {
        bean.setType(type);
    }

    public String getType() {
        return bean.getType();
    }

    public void setText(String txt) {
        bean.setText(txt);
    }

    public String getText() {
        return bean.getText();
    }

    public Page getPage() {
        return bean.getPage().getInstance();
    }

    public int getArea() {
        return bean.getArea();
    }

    public void setValue(String value) {
        bean.setValue(value);
    }

    public String getValue() {
        return bean.getValue();
    }

    public boolean isBroken() {
        return bean.isBroken();
    }

    public void setBroken(boolean b) {
        bean.setBroken(b);
    }

    //-- Enf of basic setters / getters

    // Caption feature

    public BufferedImage getImage() throws Exception {
        if (img == null) {
            img = ImageHelper.decodeToImage(getCaption());
        }
        return img;
    }

    public String getCaption() {
        return bean.getCaption();
    }

    public void takeScreenShot() throws Exception {
        if (getArea() > 0) {
            if (getPage().getUser().isPageScreenshotEnabled()
                    && getPage().getUser().isPageElementScreenshotEnabled()) {

                int x = getPos().getX();
                int y = getPos().getY();

                int w = getDim().getWidth();
                int h = getDim().getHeight();

                BufferedImage pageImg = getPage().getImage();
                BufferedImage croppedImg = ImageHelper.cropImage(pageImg, x, y, w, h, getBot().getXScale(),
                        getBot().getYScale());
                bean.setCaption(ImageHelper.encodeToString(croppedImg));
                bean.setDim(new Dimension(croppedImg.getWidth(), croppedImg.getHeight()));

                // Remove the element caption from the page caption
                pageImg = ImageHelper.eraseRect(pageImg, x, y, w, h, getBot().getXScale(), getBot().getYScale());
                getPage().setCaption(ImageHelper.encodeToString(pageImg));
            }
        }
    }

    @Override
    public int compareTo(Element element) {
        return bean.compareTo(element.getBean());
    }

    public void setPage(Page page) {
        bean.setPage(page.getBean());
    }

    public boolean isClickable() {
        if (bean.getImpl().contentEquals("Link")) {
            if (!getUser().wantsToFollowLinks()) {
                return false;
            } else {
                return !getUser().getExcludedLinks().contains(getContent());
            }
        } else if (bean.getImpl().contentEquals("Button")) {
            if (!getUser().wantsToFollowButtons()) {
                return false;
            } else {
                return !getUser().getExcludedButtons().contains(getContent());
            }
        } else {
            return true;
        }
    }

    public static boolean isVisible(WebElement element) {
        return element.isDisplayed();
    }

    public String toJson() throws IOException {
        return bean.toJson();
    }

    // For convenience only

    public User getUser() {
        return getPage().getUser();
    }

    public Bot getBot() throws Exception {
        return getUser().getBot();
    }

    public WebDriver getBrowser() throws Exception {
        return getBot().getBrowser();
    }

    public String getUrl() {
        return getPage().getUrl();
    }

    public void delete() throws Exception {
        // nothing to be done
    }

    public String toString() {
        return bean.toString();
    }

    public static boolean isIncluded(ElementBean element, Rectangle rectangle) {
        return element.getLocation().contains(rectangle);
    }

    public static boolean isIncluded(WebElement element, Rectangle rectangle) {
        Point topleft = element.getLocation();
        Dimension dim = element.getSize();
        Rectangle rectangleRef = new Rectangle(topleft.getX(), topleft.getY(), dim.getWidth(), dim.getHeight());

        return rectangleRef.contains(rectangle);
    }

    public static List<Element> filterClickableElementBeans(List<ElementBean> elements) {
        List<Element> filteredElements = new ArrayList<Element>();

        for (ElementBean element : elements) {
            if (element.getInstance().isClickable()) {
                filteredElements.add(element.getInstance());
            }
        }

        return filteredElements;
    }

    public static List<Element> filterClickableElements(List<Element> elements) {
        List<Element> filteredElements = new ArrayList();

        for (Element element : elements) {
            if (element.isClickable()) {
                filteredElements.add(element);
            }
        }

        return filteredElements;
    }

    /*
    public static WebElement filterElementByText(List<WebElement> elements, String text) throws Exception
    {
        for(WebElement element : elements)
        {
            String txt = element.getText();
            String value = element.getAttribute( "value" );
            if( txt.contentEquals( text ) || value.contentEquals( txt ))
            {
                return element;
            }
        }
        throw new Exception( "Unable to find element with text/value matching '" + text + "'." );
    }
    */
    public static ElementBean filterElementByText(List<ElementBean> elements, String text) throws Exception {
        for (ElementBean element : elements) {
            if (element.getContent().contentEquals(text)) {
                return element;
            }
        }
        return null;
    }

    public static List<ElementBean> filterElementsByText(List<ElementBean> elements, String... textList)
            throws Exception {
        List<ElementBean> matchingElements = new ArrayList<ElementBean>();

        for (ElementBean element : elements) {
            for (String txt : textList) {
                if (element.getContent().contentEquals(txt)) {
                    matchingElements.add(element);
                    break;
                }
            }
        }

        return matchingElements;
    }

    public static List<ElementBean> filterElementsByImpls(List<ElementBean> elements, String... implementations) {
        List<ElementBean> matchingElements = new ArrayList<ElementBean>();

        for (ElementBean element : elements) {
            for (String implementation : implementations) {
                if (element.getImpl().contentEquals(implementation)) {
                    matchingElements.add(element);
                    break;
                }
            }
        }

        return matchingElements;
    }

    public static List<ElementBean> filterElementsByLocations(List<ElementBean> elements, Rectangle... locations) {
        List<ElementBean> matchingElements = new ArrayList<ElementBean>();

        for (ElementBean element : elements) {
            for (Rectangle location : locations) {
                if (element.getLocation().contains(location)) {
                    matchingElements.add(element);
                    break;
                }
            }
        }

        return matchingElements;
    }

    public static WebElement filterElementByLocation(List<WebElement> elements, Rectangle rectangle)
            throws Exception {
        for (WebElement element : elements) {
            if (Element.isIncluded(element, rectangle)) {
                return element;
            }
        }
        throw new Exception("Unable to find element at location " + rectangle.toString() + ".");
    }

    public void setClicked(boolean clicked) {
        bean.setClicked(clicked);
    }

    public ElementBean getBean() {
        return bean;
    }

    public void setDisabled(boolean b) {
        bean.setDisabled(b);
    }

    public void setTarget(String target) {
        this.bean.setTarget(target);
    }

    public String getTarget() {
        return bean.getTarget();
    }

    public String getContent() {
        return bean.getContent();
    }

    public static Element buildElement(ElementBean elementBean) {
        Element element = null;
        if (elementBean.getImpl().contentEquals("Link")) {
            element = new Link(elementBean);
        } else if (elementBean.getImpl().contentEquals("Button")) {
            element = new Button(elementBean);
        }

        return element;
    }

    public boolean equals(Element element) throws IOException {
        return getBean().equals(element.getBean());
    }

    public static List<Element> filterImages(List<Element> elements) {
        List<Element> images = new ArrayList<Element>();

        for (Element element : elements) {
            if (element instanceof com.smash.revolance.ui.model.element.api.Image) {
                images.add(element);
            }
        }

        return images;
    }

    public String getBackground() {
        return bean.getBg();
    }

    public boolean isDisabled() {
        return bean.isDisabled();
    }

    public static void filterElementsIncludedInEachOthers(List<Element> content, double pageArea,
            double threshold) {
        Collections.sort(content, new Comparator<Element>() {
            @Override
            public int compare(Element o1, Element o2) {
                if (o1.getArea() > o2.getArea()) {
                    return -1;
                } else if (o1.getArea() < o2.getArea()) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });

        List<Element> hudgeBlocs = new ArrayList<Element>();

        for (Element bloc : Data.filterData(content)) {
            if (bloc.getArea() > pageArea * threshold) {
                hudgeBlocs.add(bloc);
            }
        }

        List<Element> toBeRemoved = new ArrayList<Element>();
        for (Element hudgeBloc : hudgeBlocs) {
            List<Element> elements = getElementsIn(hudgeBlocs, hudgeBloc);
            if (!elements.isEmpty()) {
                toBeRemoved.add(hudgeBloc);
            }
        }

        hudgeBlocs.removeAll(toBeRemoved);

        for (Element hudgeBloc : hudgeBlocs) {
            List<Element> matchingElements = getElementsIn(content, hudgeBloc);

            if (!matchingElements.isEmpty()) {
                content.remove(hudgeBloc);
            }
        }
    }

    public static boolean isElementsAndBlocContentMatching(List<Element> matchingElements, Element hudgeBloc) {
        // Does those elements can substitute the content of the bloc?
        List<String> blocContent = Arrays.asList(hudgeBloc.getContent().split("\\n"));
        for (Element element : matchingElements) {
            List<String> matchingElementsContent = Arrays.asList(element.getContent().split("\\n"));
            for (String matchingElementContent : matchingElementsContent) {
                if (blocContent.contains(matchingElementContent)) {
                    blocContent.remove(element.getContent());
                }
            }
        }
        return blocContent.isEmpty();
    }

    public static List<Element> getElementsIn(List<Element> contentToFilter, Element hudgeBloc) {
        List<Element> matchingElements = new ArrayList<Element>();

        // What are the elements included in the bloc?
        for (Element element : contentToFilter) {
            if (element != hudgeBloc && !element.getContent().isEmpty() && hudgeBloc.isIncluded(element)) {
                matchingElements.add(element);
            }
        }

        return matchingElements;
    }

    public static Element getBiggestElement(List<Element> elements) {
        if (elements == null) {
            return null;
        }
        if (elements.isEmpty()) {
            return null;
        }
        int maxArea = 0;
        Element pageElement = null;
        for (Element element : elements) {
            if (element.getArea() > maxArea) {
                pageElement = element;
                maxArea = element.getArea();
            }
        }
        return pageElement;
    }

}