com.smash.revolance.ui.model.sitemap.SiteMap.java Source code

Java tutorial

Introduction

Here is the source code for com.smash.revolance.ui.model.sitemap.SiteMap.java

Source

package com.smash.revolance.ui.model.sitemap;

/*
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 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>.
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

import com.smash.revolance.ui.materials.JsonHelper;
import com.smash.revolance.ui.model.element.api.ElementBean;
import com.smash.revolance.ui.model.helper.BotHelper;
import com.smash.revolance.ui.model.helper.UrlHelper;
import com.smash.revolance.ui.model.page.IPage;
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.UserBean;
import org.apache.commons.io.FileUtils;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.kohsuke.graphviz.Edge;
import org.kohsuke.graphviz.Graph;
import org.kohsuke.graphviz.Node;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * User: wsmash
 * Date: 20/02/13
 * Time: 10:43
 */
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE)
public class SiteMap {
    private long date = 0;

    private HashMap<String, PageBean> sitemap = null;

    @JsonIgnore
    private static final String RED = "#FF0000";

    @JsonIgnore
    private static final String BLUE = "#0000FF";

    @JsonIgnore
    private static final String GRAY = "#222222";

    @JsonIgnore
    private static final String GREEN = "#00FF00";

    @JsonIgnore
    private static final String BLACK = "#000000";

    private UserBean user;

    /*
    public File getSitemapDotFile() throws IOException
    {
    String sitemapDotFileName = "sitemap.dot";
    return new File( user.getSitemapFolder(), sitemapDotFileName );
    }
        
    public File getSitemapImgFile() throws IOException
    {
    String sitemapImgFileName = "sitemap.svg";
    return new File( user.getSitemapFolder(), sitemapImgFileName );
    }
    */

    private SiteMap() {
        sitemap = new HashMap();
    }

    public SiteMap(UserBean user) {
        this();
        setUser(user);
    }

    private void setUser(UserBean user) {
        this.user = user;
    }

    /**
     * Retrieve all the original pages of the application
     *
     * @return
     */
    public Collection<PageBean> getPages() {
        return sitemap.values();
    }

    /**
     * Retrieve the number of pages in the sitemap
     */
    public int getPagesCount() {
        return getPages().size();
    }

    /**
     * Retrieve a page. Either it's an original if first time asked for this page
     * Or a variant of the original page when the url hasn't changed.
     *
     * @return
     * @throws Exception
     */
    public PageBean getPage(String url, boolean generate) throws Exception {
        PageBean page = findPageByUrl(url);
        if (page == null) {
            if (generate) {
                page = Page.createPage(getUser().getInstance(), url,
                        getUser().getInstance().getBot().getCurrentTitle());
            }
        }
        return page;
    }

    /**
     * Only register pages that are original and not variant
     *
     * @param page
     * @throws Exception
     */
    public void addPage(Page page) {
        if (page.isOriginal()) {
            sitemap.put(page.getUrl(), page.getBean());
        }
    }

    public PageBean findPageByUrl(String url) {
        if (sitemap.isEmpty()) {
            return null;
        } else {
            PageBean page = getPage(url);
            if (page != null) {
                if (UrlHelper.containsHash(url)) {
                    String hash = UrlHelper.getHash(url);
                    return page.getInstance().findVariantByHash(hash);
                }
            }
            return page;
        }
    }

    private PageBean getPage(String url) {
        PageBean page = null;
        for (String urlRegistered : sitemap.keySet()) {
            if (UrlHelper.areEquivalent(urlRegistered, url)) {
                return sitemap.get(urlRegistered);
            }
        }
        return page;
    }

    public List<PageBean> getBrokenPages() {
        List<PageBean> brokenPages = new ArrayList<PageBean>();
        for (PageBean page : getPages()) {
            if (page.isBroken()) {
                brokenPages.add(page);
            }
        }
        return brokenPages;
    }

    public List<String> getBrokenLinks() {
        List<String> brokenLinks = new ArrayList<String>();
        for (PageBean page : getBrokenPages()) {
            brokenLinks.add(page.getSource().getContent());
        }
        return brokenLinks;
    }

    public Graph convertToGraph(String title) throws Exception {

        Graph graph = new Graph();

        graph.attr("label", title);
        graph.attr("mindist", "15");
        graph.attr("ratio", "auto");
        graph.attr("overlap", "false");
        graph.attr("ranksep", "15");
        graph.attr("weight", "2");
        graph.attr("splines", "true");
        graph.attr("margin", "10");

        List<Edge> edges = new ArrayList<Edge>();
        Map<String, Node> nodes = new HashMap<String, Node>();

        for (PageBean page : getPages()) {
            Node node = createNode(page);
            graph.node(node);
            nodes.put(page.getUrl(), node);
        }

        for (PageBean page : getPages()) {
            for (ElementBean link : page.getLinks()) {
                Edge edge = new Edge(nodes.get(page.getUrl()), nodes.get(link.getHref()));
                edge.attr("label", link.getHref());

                if (!isAlreadyDefined(edge, edges)) {
                    // if( Link.containsLink( page.getBrokenLinks(), link.getHref(), element.getLocation(), element.getSize()) )
                    // {
                    edge.attr("color", RED);
                    // }
                    graph.edge(edge);
                    edges.add(edge);
                }
            }
        }

        /*
            
        Map<Node, Integer> countsPos = new HashMap<Node, Integer>();
        Map<Node, Integer> countsNeg = new HashMap<Node, Integer>();
        for(Edge edge : edges)
        {
        if(!countsPos.containsKey(edge.dst))
        {
            countsPos.put( edge.dst, new Integer(0) );
        }
        countsPos.put(edge.dst, countsPos.get(edge.dst) + 1);
            
        if(!countsNeg.containsKey(edge.src))
        {
            countsNeg.put( edge.src, new Integer(0) );
        }
        countsPos.put(edge.src, countsPos.get(edge.src) + 1);
        }
            
        Node nodePos = getMaxNode(countsPos);
        Node nodeNeg = getMaxNode(countsNeg);
            
        */

        return graph;
    }

    private Node getMaxNode(Map<Node, Integer> countsPos) {
        int max = 0;
        Node nodeMaxPos = null;
        boolean first = true;
        for (Node nodePos : countsPos.keySet()) {
            if (first) {
                max = countsPos.get(nodePos);
                nodeMaxPos = nodePos;
                first = false;
                continue;
            }

            if (max < countsPos.get(nodePos)) {
                max = countsPos.get(nodePos);
                nodeMaxPos = nodePos;
            }
        }
        return nodeMaxPos;
    }

    private boolean isAlreadyDefined(Edge edge, List<Edge> edges) {
        String label = edge.attr("label");
        for (Edge iterator : edges) {
            String dstLabel = iterator.attr("label");
            boolean dstMatch = dstLabel.contentEquals(label);
            if (dstMatch) {
                return true;
            }
        }
        return false;
    }

    private Node createNode(PageBean page) throws Exception {
        Node node = new Node();
        String url = page.getUrl();
        String urlString;
        if (url == null)
            urlString = node.toString();
        else
            urlString = escape(url);

        node.id(urlString);

        node.attr("label", page.getTitle());
        node.attr("fixedsize", "true");
        node.attr("height", String.valueOf("4"));
        node.attr("width", String.valueOf("3"));
        node.attr("shape", "box");

        if (!page.isBroken()) {
            setColor(node, BLUE);
            if (page.isHome()) {
                setColor(node, GREEN);
            }
        } else {
            setColor(node, RED);
        }
        setImage(node, page.getCaption());
        setUrl(node, page.getUrl());
        return node;
    }

    private String escape(String string) {
        return "\"" + string + "\"";
    }

    private void setImage(Node node, String caption) throws IOException {
        if (caption == null) {
            return;
        }

        // File root = user.getSitemapFolder();
        // String relCaption = FileHelper.getRelativePath( root, caption );

        node.attr("image", caption);

    }

    private void setUrl(Node node, String url) {
        if (url != null) {
            node.attr("URL", url);
        }
    }

    private void setColor(Node node, String color) {
        node.attr("color", color);
    }

    public void setHomeNode(Node node) {
        node.attr("shape", "box");
        setColor(node, BLUE);
    }

    public String getDomain() {
        return user.getDomain();
    }

    public UserBean getUser() {
        return user;
    }

    public boolean isEmpty() {
        return sitemap.isEmpty();
    }

    public Collection<PageBean> getPagesWithVariations() {
        List<PageBean> pages = new ArrayList<PageBean>();
        pages.addAll(getPages());

        for (PageBean page : getPages()) {
            pages.addAll(page.getVariants());
        }
        return pages;
    }

    public boolean hasBeenExplored(String url) throws Exception {
        PageBean page = findPage(url);

        if (page != null) {
            if (page.getInstance().hasBeenExplored()) {
                return true;
            } else {
                for (ElementBean element : page.getClickableContent()) {
                    if (!element.isBroken() && !element.hasBeenClicked() && element.getInstance().isClickable()
                            && BotHelper.rightDomain(getUser().getDomain(), url)) {
                        return false;
                    }
                }
                return true;
            }
        } else {
            return false;
        }
    }

    public PageBean findPage(String url) throws Exception {
        PageBean page;

        if (url.isEmpty()) {
            return null;
        } else if (!UrlHelper.containsHash(url)) {
            page = findPageByUrl(url);
        } else {
            url = UrlHelper.removeHash(url);
            page = findPageByUrl(url);
            if (page != null) {
                page = page.getInstance().findVariantByHash(UrlHelper.getHash(url));
            }
        }

        return page;
    }

    public ElementBean getFirstUnexploredElement(String url) throws Exception {
        PageBean page = findPage(url);

        if (page == null) {
            return null;
        } else {
            if (!page.getInstance().hasBeenExplored()) {
                for (ElementBean element : page.getClickableContent()) {
                    if (!element.isBroken() && !element.hasBeenClicked() && element.getInstance().isClickable()) {
                        return element;
                    }
                }
            }
            return null;
        }
    }

    public void delPage(IPage page) {
        if (page.isOriginal()) {
            if (sitemap.containsKey(page.getUrl())) {
                sitemap.remove(page.getUrl());
            }
        }
    }

    public static SiteMap fromJson(File json) throws IOException {
        return fromJson(FileUtils.readFileToString(json));
    }

    public static SiteMap fromJson(String json) throws IOException {
        SiteMap sitemap = (SiteMap) JsonHelper.getInstance().map(SiteMap.class, json);
        UserBean user = sitemap.getUser();

        // Attach user and elements to the page
        for (PageBean page : sitemap.getPages()) {
            page.setUser(user);
            for (ElementBean element : page.getContent()) {
                element.setPage(page);
            }
        }

        // Attach original page reference to each page
        for (PageBean originalPage : sitemap.getPages()) {
            for (PageBean page : sitemap.getPages()) {
                if (page.getOriginalPageId().contentEquals(originalPage.getId())) {
                    page.setOriginal(originalPage);
                }
            }
        }

        return sitemap;
    }

    public void setHome(String home) {
        this.user.setHome(home);
    }

    public PageBean findPageByInternalId(String pageId) {
        for (PageBean page : getPages()) {
            if (page.getId().contentEquals(pageId)) {
                return page;
            }
        }
        return null;
    }

    public long getDate() {
        return date;
    }

    public void setDate(final long date) {
        this.date = date;
    }

}