/* 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; import static it.slumdroid.utilities.Resources.GUITREE; import static it.slumdroid.utilities.Resources.GUITREE_DIR; import static it.slumdroid.utilities.Resources.MAX_ES; import static it.slumdroid.utilities.Resources.NEW_LINE; import static it.slumdroid.utilities.Resources.TOOL_TARGET; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Random; import java.util.prefs.Preferences; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.DocumentType; import org.w3c.dom.Element; import org.xml.sax.InputSource; // TODO: Auto-generated Javadoc /** * The Class Tools. */ public class Tools { /** The metadata. */ private static String metadata = new String(); // Preference Editor Utilities /** * Clean node. * * @param prefs the prefs */ public void cleanNode(Preferences prefs) { try { prefs.removeNode(); } catch (Exception e) { e.printStackTrace(); } } /** * Load node. * * @param path the path * @return true, if successful */ public boolean loadNode(String path) { InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(path)); Preferences.importPreferences(is); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * Save node. * * @param args the args * @param prefs the prefs */ public void saveNode(String args, Preferences prefs) { FileOutputStream fos; try { fos = new FileOutputStream(args); prefs.exportSubtree(fos); } catch (Exception e) { e.printStackTrace(); } } /** * New seed. * * @param seed the seed * @return the long */ public long newSeed(String seed) { Random Rs = new Random(Long.parseLong(seed)); Long generatedSeed = Rs.nextLong(); return generatedSeed; } /** * Dir list by ascending date. * * @param folder the folder * @return the file[] */ public File[] dirListByAscendingDate(File folder) { if (!folder.isDirectory()) { return null; } File files[] = folder.listFiles(); Arrays.sort(files, new Comparator<Object>() { public int compare(final Object o1, final Object o2) { return new Long(((File) o1).lastModified()).compareTo(new Long(((File) o2).lastModified())); } }); return files; } // XML Utilities /** * Xml writer. * * @param path the path * @param builder the builder */ public void xmlWriter(String path, StringBuilder builder){ xmlWriter(path, builder, path); } /** * Xml writer. * * @param path the path * @param builder the builder * @param output the output */ public void xmlWriter(String path, StringBuilder builder, String output){ Document doc = null; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); DocumentBuilder dombuilder = factory.newDocumentBuilder(); try { doc = dombuilder.parse( new InputSource( new StringReader( builder.toString() ) ) ); } catch (Exception e) { e.printStackTrace(); } Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); DocumentType doctype = doc.getDoctype(); if(doctype != null) { if (doctype.getPublicId() != null) { transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId()); } if (doctype.getSystemId() != null) { transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId()); } } DOMSource domSource = new DOMSource(doc); StreamResult outputstream = new StreamResult(output); transformer.transform(domSource, outputstream); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } } // Split Utilities /** * Split. * * @param path the path * @param folder the folder * @param output the output * @param suboutput the suboutput */ public void split(String path, String folder, String output, String suboutput) { if (!new File(folder).exists()) { new File(folder).mkdir(); } String guitreeXml = path.concat(output); File file = new File(guitreeXml); if (file.exists()) { file.renameTo(new File(new File(folder), suboutput + System.currentTimeMillis() + ".xml")); } try { new File(guitreeXml).createNewFile(); } catch (Exception e) { e.printStackTrace(); } } // Coverage Text Parsing Utilities /** * Cov text parsing. * * @param path the path */ public void covTextParsing(String path) { BufferedReader inputStream1 = null; try { inputStream1 = new BufferedReader (new FileReader (path)); String line = new String(); while ((line = inputStream1.readLine()) != null ) { if (line.contains("all classes")) { System.out.println("Actual Coverage is"); System.out.println("[class, %] [method, %] [block, %] [line, %]"); System.out.println(line.replace("all classes", "").replace(",",".")); inputStream1.close(); return; } } } catch (Exception e) { e.printStackTrace(); } finally { try { inputStream1.close(); } catch (Exception e) { e.printStackTrace(); } } } //Coverage Generator Utilities /** * Cov generator. * * @param header the header */ public void covGenerator(String header){ try { PrintWriter out = new PrintWriter ("../coverage/Copertura.bat"); String esFiles = new Tools().coverage(out); out.print(header + esFiles); out.close(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } /** * Coverage. * * @param out the out * @return the string */ private String coverage(PrintWriter out){ int esCounter = 0; String[] theFiles = showFiles(); String esFiles = new String(); String name = new String(); String comma = new String(); out.println("set EMMA=java -cp %EMULATORPATH%\\lib\\emma_device.jar emma"); for (String ecFiles: theFiles) { name = "coverage" + esCounter + ".es"; out.println("%EMMA% merge -in " + metadata + ecFiles + " -out " + name); esFiles += comma + name; comma = ","; esCounter++; } return esFiles; } /** * Show files. * * @return the string[] */ private static String[] showFiles() { ArrayList<String> fileList = new ArrayList<String>(); int counter = 0; String theFiles = new String(); try{ File[] candidates = new File("../coverage/").listFiles(); for (File file : candidates) { if (file.isDirectory()) { continue; } if (file.getName().endsWith(".em")) { metadata = file.getName(); } else if (file.getName().endsWith(".ec")) { theFiles += "," + file.getName(); counter++; } if (counter >= MAX_ES) { fileList.add(theFiles); theFiles = new String(); counter = 0; } } } catch (Exception e) { e.printStackTrace(); } if (!theFiles.equals("")) { fileList.add(theFiles); theFiles = new String(); } if (fileList.size() > 0) { String[] output = new String [fileList.size()]; output = fileList.toArray(output); return output; } return null; } // BuildControl Utilities /** * Control the Building. * * @param path the path */ public void buildControl(String path) { try { boolean success = false; BufferedReader inputStream1 = new BufferedReader (new FileReader (path)); int count = 0; String line = new String(); while ((line = inputStream1.readLine()) != null ) { if (line.contains("[exec] Success")) { count++; if (count == 2) { success = true; } } } inputStream1.close(); if (success){ PrintWriter outputStream1 = new PrintWriter ("build.txt"); outputStream1.write("completed"); outputStream1.close(); } } catch (Exception e) { e.printStackTrace(); } } // ReTargeting Utilities /** * Retarget. * * @param fileName the file name * @param targetPackage the target package */ public void retarget(String fileName, String targetPackage) { DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = null; Document document = null; try { builder = builderFactory.newDocumentBuilder(); document = builder.parse(new FileInputStream(fileName)); } catch (Exception e) { e.printStackTrace(); } Element manifest = document.getDocumentElement(); Element target = (Element)manifest.getElementsByTagName("instrumentation").item(0); target.setAttribute("android:targetPackage", targetPackage); String newManifest = new String(); try { newManifest = toXml(manifest); } catch (Exception e) { e.printStackTrace(); } PrintWriter output; try { output = new PrintWriter (fileName); output.println(newManifest); output.close(); } catch (Exception e) { e.printStackTrace(); } } /** * To xml. * * @param dom the dom * @return the string * @throws TransformerFactoryConfigurationError the transformer factory configuration error * @throws TransformerException the transformer exception */ private String toXml(Element dom) throws TransformerFactoryConfigurationError, TransformerException { DOMSource theDom = new DOMSource(dom); StringWriter output = new StringWriter(); Transformer t = TransformerFactory.newInstance().newTransformer(); t.setOutputProperty(OutputKeys.METHOD, "xml"); t.transform(theDom, new StreamResult(output)); return output.toString(); } /** * Xml to string. * * @param doc the doc * @return the string * @throws Exception the exception */ public String xmlToString(Document doc) throws Exception { try { StringWriter stw = new StringWriter(); Transformer serializer = TransformerFactory.newInstance().newTransformer(); serializer.transform(new DOMSource(doc), new StreamResult(stw)); return stw.toString(); } catch (Exception e) { e.printStackTrace(); } return new String(); } // TrasformActivity Utilities /** * Traslate. * * @param path the path * @param output the output */ public void traslate(String path, String output) { String xmlHead = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; StringBuilder builder = new StringBuilder(); builder.append(xmlHead + "<ACTIVITY_STATES>"); try{ BufferedReader inputStream1 = new BufferedReader (new FileReader (path)); String line = new String(); while ((line = inputStream1.readLine()) != null ) { builder.append(line.replace(xmlHead, "") .replace("START_STATE", "ACTIVITY_STATE") .replace("FINAL_STATE", "ACTIVITY_STATE")); } builder.append("</ACTIVITY_STATES>"); inputStream1.close(); new Tools().xmlWriter(path, builder, output); } catch (Exception e) { e.printStackTrace(); } } // Merge Utilities /** * Merge g. * * @param path the path */ public void mergeG(String path) { String guitreeXml = path.concat(GUITREE); File dir = new File(GUITREE_DIR); if (dir.exists() && dir.isDirectory()) { merge(guitreeXml, GUITREE_DIR); } } /** * Merge. * * @param xml the xml * @param dir the dir */ private void merge(String xml, String dir) { int count = 0; boolean session_found = false; try{ File fl[] = new Tools().dirListByAscendingDate( new File(dir) ); if (fl.length > 0){ FileWriter outFile = new FileWriter(xml, false); PrintWriter out = new PrintWriter(outFile); for (File f : fl) { FileReader inFile = new FileReader(f); BufferedReader in = new BufferedReader(inFile); String s = null; while((s = in.readLine()) != null) { if (!s.equals("")) { count++; if (s.contains("</SESSION>")) { session_found = true; } out.println(s); } } inFile.close(); } if (!session_found) { out.println("</SESSION>"); } out.close(); } } catch (Exception e){ e.printStackTrace(); } if (count == 0) { new File(xml).delete(); } } // UpdateProperties Utilities /** * Update properties. * * @param autPath the aut path */ public void updateProperties(String autPath) { String path = new String(autPath.concat("/project.properties")); String target = new String("target=android-"); String density = new String("split.density"); StringBuilder builder = new StringBuilder(); try{ BufferedReader inputStream1 = new BufferedReader (new FileReader (path)); String line = new String(); while ((line = inputStream1.readLine()) != null ) { if (line.contains(target)) { builder.append(target + TOOL_TARGET + NEW_LINE); } else { if (line.contains(density)) { builder.append(NEW_LINE); } else { builder.append(line + NEW_LINE); } } } inputStream1.close(); PrintWriter outputStream1 = new PrintWriter (path); outputStream1.write(builder.toString()); outputStream1.close(); redensity(new String(autPath.concat("/AndroidManifest.xml"))); } catch (Exception e) { e.printStackTrace(); } } /** * Redensity. * * @param fileName the file name */ public void redensity(String fileName) { DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = null; Document document = null; try { docBuilder = builderFactory.newDocumentBuilder(); document = docBuilder.parse(new FileInputStream(fileName)); } catch (Exception e) { e.printStackTrace(); } Element manifest = document.getDocumentElement(); Element target = (Element)manifest.getElementsByTagName("supports-screens").item(0); if (target == null) { StringBuilder builder = new StringBuilder(); // https://code.google.com/p/robotium/wiki/QuestionsAndAnswers String screens = new String("\t<supports-screens android:smallScreens=\"true\" android:normalScreens=\"true\" android:largeScreens=\"true\" android:anyDensity=\"true\" />"); try{ InputStreamReader inputStream = new InputStreamReader(new FileInputStream(new File(fileName)), "UTF-8"); BufferedReader reader = new BufferedReader (inputStream); String line = new String(); while ((line = reader.readLine()) != null ) { if (line.contains("</manifest>")) { builder.append(screens + NEW_LINE + line); } else { byte[] stringBytesISO = line.getBytes("ISO-8859-1"); builder.append(new String(stringBytesISO, "UTF-8") + NEW_LINE); } } reader.close(); PrintWriter outputStream = new PrintWriter(fileName); outputStream.write(builder.toString()); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } } else { target.setAttribute("android:anyDensity", "true"); target.setAttribute("android:smallScreens", "true"); target.setAttribute("android:normalScreens", "true"); target.setAttribute("android:largeScreens", "true"); String newManifest = new String(); try { newManifest = toXml(manifest); } catch (Exception e) { e.printStackTrace(); } PrintWriter output; try { output = new PrintWriter (fileName); output.println(newManifest); output.close(); } catch (Exception e) { e.printStackTrace(); } } } // Trend Utilities /** * Trend test. * * @param inputPath the input path */ public void trendTest(String inputPath) { if (inputPath.equals("")) { inputPath = new String(System.getProperty("user.dir")); } final String TASK = new String("Playing Task "); final String TIME = new String("Time: "); final String ACTUAL = new String("Actual Coverage is"); double seconds = 0; int task = 0; int time = 0; String coverage = new String(); Stats item = new Stats(task, time, coverage); BufferedReader inputStream1 = null; ArrayList<Stats> list = new ArrayList<Stats>(); boolean interesting = false; try { inputStream1 = new BufferedReader (new FileReader (inputPath + "\\test.txt")); String line = new String(); while ((line = inputStream1.readLine()) != null ) { if (line.contains(TASK)) { task = Integer.valueOf(line.replace(TASK, "").replace(" ", "")) + 1; } if (line.contains(ACTUAL)) { for (int jump = 0; jump < 2; jump++) { line = inputStream1.readLine(); } String[] coverageLine = line.replace("\t","").replace("!", "").split(Pattern.quote(")")); String tempLoc = new String(coverageLine[coverageLine.length - 1]) + ")"; if (!coverage.equals(tempLoc)) { interesting = true; coverage = new String(tempLoc); } } if (line.contains(TIME)) { seconds += Double.valueOf(line.replace(TIME, "")); String round = String.valueOf(seconds).replace("."," ").split(" ")[0]; time = Integer.valueOf(round); } if (interesting) { item = new Stats(task, time, coverage); list.add(item); interesting = false; } } } catch (Exception e) { e.printStackTrace(); } finally { try { inputStream1.close(); } catch (IOException e) { e.printStackTrace(); } } if (time != 0) { item = new Stats(task, time, coverage); // Last Task list.add(item); PrintWriter outputStream1 = null; if (!new File(inputPath + "\\output").exists()) { new File(inputPath + "\\output").mkdir(); } try { String format = "%-6s %12s \t%-12s"; outputStream1 = new PrintWriter (inputPath + "\\output\\trend.txt"); outputStream1.write(String.format(format, "Task", "Coverage", "Time")); outputStream1.write(NEW_LINE); for (int index = 0; index < list.size(); index++) { item = list.get(index); outputStream1.flush(); format = "%-6s %-1s\t%-12s"; String row = String.format(format, String.format("%04d", item.getTaskID()), item.getLoC().replace(".", ",").replace("% ", "%"), String.format("%04d", item.getActualTime())); outputStream1.write(row); outputStream1.write(NEW_LINE); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { outputStream1.close(); } } } /** * The Class Stats. */ protected class Stats { /** The task id. */ private int taskID; /** The actual time. */ private int actualTime; /** The Lo c. */ private String LoC; /** * Instantiates a new stats. * * @param id the id * @param actual the actual * @param coverage the coverage */ public Stats(int id, int actual, String coverage){ this.taskID = id; this.actualTime = actual; this.LoC = new String(coverage); } /** * Gets the task id. * * @return the task id */ public int getTaskID() { return taskID; } /** * Gets the actual time. * * @return the actual time */ public int getActualTime() { return actualTime; } /** * Gets the Lines of Code Coverage. * * @return the Lines of Code Coverage */ public String getLoC() { return LoC; } } }