Java tutorial
/* * Copyright 2016 Sven Wiemann * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the * License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES * OR CONDITIONS OF ANY KIND, either express or implied. See the License for * the specific language governing permissions and limitations under the License. */ package output; import java.awt.Image; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.text.StrSubstitutor; /** * Create a Tikz/PGF Graph based upon the test data. * @author Sven Wiemann * */ public class TikzTex { // The Folder the output should be written to private String outputDir = "src/main/resources/output/"; public TikzTex(String outputDir) { this.outputDir = outputDir; } /** * Use PDF-Latex to parse the .tex file * @param file the source File containing the Data * @throws IOException */ public void genPdf(File file) throws IOException { ProcessBuilder pb = new ProcessBuilder("pdflatex", "-shell-escape", file.getAbsolutePath()); File directory = new File(outputDir); pb.directory(directory); Process p; try { p = pb.start(); // We need to parse the Error and the Output generated by pdflatex StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR"); StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUTPUT"); errorGobbler.start(); outputGobbler.start(); // Wait until its done int exitVal = p.waitFor(); // Spawn a Frame with the Image JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); String imgPath = file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - 4) + ".png"; ImageIcon icon = new ImageIcon(imgPath); // resize Image img = icon.getImage(); double ratio = (double) icon.getIconWidth() / icon.getIconHeight(); Image newimg = img.getScaledInstance((int) (Math.round(600 * ratio)), 600, java.awt.Image.SCALE_SMOOTH); icon = new ImageIcon(newimg); JLabel imgLabel = new JLabel(icon); JScrollPane scrollPanel = new JScrollPane(imgLabel); frame.getContentPane().add(scrollPanel); frame.setSize(1280, 720); frame.setVisible(true); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } /** * Replace the Patterns in the Template.tex File with the actual Data. * The y-axis contains the runtimes * @param texFile template File * @param dataFile File with the Test results * @param xDef which column of the Test results should be used on the x-axis * @param title Title of the Graph * @param xDesc Description of the x-Axis * @return * @throws IOException */ public File insertAlgorithmResults(File texFile, File dataFile, String xDef, String title, String xDesc) throws IOException { Map<String, String> valuesMap = new HashMap<>(); String dataString = readDataFile(dataFile); // Put the Patterns and the replacements into a map valuesMap.put("ALGORITHM_RESULTS", dataString); valuesMap.putAll(getAlgorithms(dataFile)); valuesMap.put("Cat", xDef); valuesMap.put("Title", title); valuesMap.put("xDesc", xDesc); valuesMap.put("yDef", "CalcTime"); valuesMap.put("yDesc", "Laufzeit in Sek."); // Write the complete file Path path = Paths.get(texFile.getAbsolutePath()); String content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8); StrSubstitutor sub = new StrSubstitutor(valuesMap); content = sub.replace(content); File output = new File(outputDir + System.currentTimeMillis() + ".tex"); FileUtils.writeStringToFile(output, content, StandardCharsets.UTF_8); return output; } /** * Replace the Patterns in the Template.tex File with the actual Data * The content of the y-Axis could be replaced by this method. * @param texFile template File * @param dataFile File with the Test results * @param xDef which column of the Test results should be used on the x-axis * @param title Title of the Graph * @param xDesc Description of the x-Axis * @param yDef which column of the Test results should be used on the y-axis * @param yDesc Description of the y-Axis * @return * @throws IOException */ public File insertAlgorithmResults(File texFile, File dataFile, String xDef, String title, String xDesc, String yDef, String yDesc) throws IOException { Map<String, String> valuesMap = new HashMap<>(); String dataString = readDataFile(dataFile); // Put the Patterns and the replacements into a map valuesMap.put("ALGORITHM_RESULTS", dataString); valuesMap.putAll(getAlgorithms(dataFile)); valuesMap.put("Cat", xDef); valuesMap.put("Title", title); valuesMap.put("xDesc", xDesc); valuesMap.put("yDef", yDef); valuesMap.put("yDesc", yDesc); // Write the complete file Path path = Paths.get(texFile.getAbsolutePath()); String content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8); StrSubstitutor sub = new StrSubstitutor(valuesMap); content = sub.replace(content); File output = new File(outputDir + System.currentTimeMillis() + ".tex"); FileUtils.writeStringToFile(output, content, StandardCharsets.UTF_8); return output; } /** * Which Algorithms are used in the Test? * @param dataFile * @return * @throws IOException */ public Map<String, String> getAlgorithms(File dataFile) throws IOException { Map<String, String> valuesMap = new HashMap<>(); BufferedReader br = new BufferedReader(new FileReader(dataFile)); String line = br.readLine(); // reject first line line = br.readLine(); int i = 1; // Read every data file, new Algorithm found? Put it into the Map! while (line != null) { String[] values = line.split("\t"); if (!valuesMap.containsValue(values[values.length - 1])) { valuesMap.put("Algo" + i, values[values.length - 1]); i++; } line = br.readLine(); } br.close(); return valuesMap; } public String readDataFile(File dataFile) throws IOException { return new String(Files.readAllBytes(Paths.get(dataFile.getAbsolutePath())), StandardCharsets.UTF_8); } } /** * Based upon http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html by Michael C. Daconta * */ class StreamGobbler extends Thread { InputStream inputStream; String type; StreamGobbler(InputStream inputStream, String type) { this.inputStream = inputStream; this.type = type; } public void run() { try { InputStreamReader inputReader = new InputStreamReader(inputStream); BufferedReader br = new BufferedReader(inputReader); String line = br.readLine(); while (line != null) { line = br.readLine(); } } catch (IOException e) { e.printStackTrace(); } } }