/* This file is part of SlumDroid <https://code.google.com/p/slumdroid/>. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * 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 <http://www.gnu.org/licenses/gpl-3.0.txt> * for more details. * * Copyright (C) 2013-2015 Gennaro Imparato */ package it.slumdroid.utilities.module.androidtest.stats; import static it.slumdroid.utilities.Resources.BREAK; import static it.slumdroid.utilities.Resources.NEW_LINE; import static it.slumdroid.utilities.Resources.TAB; import it.slumdroid.droidmodels.guitree.GuiTree; import it.slumdroid.droidmodels.model.ActivityState; import it.slumdroid.droidmodels.model.Task; import it.slumdroid.droidmodels.model.Transition; import it.slumdroid.droidmodels.xml.NodeListIterator; import it.slumdroid.utilities.module.androidtest.efg.EventFlowGraph; import it.slumdroid.utilities.module.androidtest.graphviz.Edge; import it.slumdroid.utilities.module.androidtest.graphviz.Node; import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.Map; import java.util.Set; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Element; // TODO: Auto-generated Javadoc /** * The Class ReportGenerator. */ public class ReportGenerator extends StatsReport { /** The activity. */ private Set<String> activity; /** The activity states. */ private Set<String> activityStates; /** The branch. */ private int branch = 0; /** The depth. */ private int depth = 0; /** The efg. */ private EventFlowGraph efg; /** The event report. */ private InteractionStats eventReport; /** The leaves. */ private int leaves = 0; /** The session. */ private GuiTree session; /** The task report. */ private TaskStats taskReport; /** * Instantiates a new report generator. * * @param guiTree the gui tree * @param txtFile the txt file name */ public ReportGenerator(GuiTree guiTree, String txtFile) { this.session = guiTree; this.activity = new HashSet<String>(); this.activityStates = new HashSet<String>(); this.taskReport = new TaskStats(txtFile); this.eventReport = new InteractionStats(); try { this.efg = EventFlowGraph.fromSession(this.session); } catch (ParserConfigurationException e) { e.printStackTrace(); } } /** * Evaluate. */ public void evaluate() { ArrayList<Edge> edges = new ArrayList<Edge>(); for (Task theTask: this.session) { taskReport.analyzeTask(theTask); boolean first = true; int currentDepth = 0; ActivityState start = null; ActivityState finish = null; for (Transition transition: theTask) { currentDepth++; eventReport.analyzeInteractions(transition); if (first) { countStates(transition.getStartActivity()); } countStates(transition.getFinalActivity()); first = false; start = transition.getStartActivity(); finish = transition.getFinalActivity(); } this.depth = max(this.depth, currentDepth); Edge edge = new Edge(new Node (start), new Node (finish)); edges.add(edge); } Hashtable<String, Integer> branches = new Hashtable<String, Integer>(); for (Edge edge:edges) { inc (branches, edge.getFrom().getId()); } for (Map.Entry<String,Integer> entry: branches.entrySet()) { this.branch = max(this.branch, entry.getValue()); } if (this.efg != null) { countLeaves(); } } /** * Count leaves. */ private void countLeaves() { Element efg = (Element) this.efg.getDom().getChildNodes().item(0); this.countLeaves (efg, 0); } /** * Count leaves. * * @param event the event * @param depth the depth */ private void countLeaves(Element event, int depth) { boolean atLeastOneChild = false; for (Element element: new NodeListIterator (event)) { atLeastOneChild = true; this.countLeaves(element, depth+1); } if (!atLeastOneChild) { this.leaves++; } } /* (non-Javadoc) * @see it.slumdroid.utilities.module.androidtest.stats.StatsReport#getReport() */ public String getReport() { evaluate(); StringBuilder builder = new StringBuilder(); builder.append(this.taskReport + NEW_LINE); builder.append( "Model Information: " + NEW_LINE + TAB + "Different GUI States: " + this.activityStates.size() + NEW_LINE + TAB + "Different Activities: " + this.activity.size() + NEW_LINE + TAB + "Leaves of GUITree: " + this.leaves + NEW_LINE + TAB + "Max Reached Depth: " + this.depth + NEW_LINE + TAB + "Max Reached Branch: " + this.branch + BREAK + this.eventReport); return builder.toString(); } /** * Count states. * * @param state the state */ private void countStates(ActivityState state) { this.activityStates.add(state.getId()); if (state.isFailure() || state.isExit() || state.isCrash()) { return; } if (!state.getName().equals("")) { this.activity.add(state.getName()); } } }