Java tutorial
/******************************************************************************* * Copyright (c) 2015-2017 Resilient Computing Lab, University of Firenze. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Leonardo Montecchi lmontecchi@unifi.it ******************************************************************************/ package it.unifi.rcl.chess.traceanalysis; import it.unifi.rcl.chess.traceanalysis.distributions.CHDistribution; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PushbackInputStream; import java.io.Reader; import java.security.Permission; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.zip.GZIPInputStream; import javax.swing.JPanel; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.ChartUtilities; import org.jfree.chart.ChartFactory; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import monitoringService.MonitoringService; import monitoringService.distributions.Distribution; import monitoringService.mechanisms.MechanismAD; import monitoringService.mechanisms.MechanismAD_KS; import monitoringService.mechanisms.MechanismKS; import monitoringService.mechanisms.PhaseDetectionMechanism; import monitoringService.util.MonitoringServiceException; public class Trace { private static char SKIPLINE_CHAR = '#'; // character meaning that a line should be discarded private static String NO_NAME = "{unnamed}"; private ArrayList<Double> data; // the data private String name = NO_NAME; public Trace() { data = new ArrayList<Double>(); } public Trace(File file) { this(); name = file.getAbsolutePath(); try { InputStream is = new FileInputStream(file); // check if the file is compressed with gzip boolean isZipped = Trace.checkGZIP(is); is.close(); is = new FileInputStream(file); if (isZipped) { is = new GZIPInputStream(is); } loadFromStream(is); is.close(); } catch (IOException e) { System.out.println(e); } } public Trace(InputStream is) { this(); try { loadFromStream(is); } catch (IOException e) { System.out.println(e); } } public void setName(String name) { this.name = name; } public String getName() { return name; } public String getName(int lenght) { return Utils.abbreviateMiddle(getName(), "...", lenght); } private void loadFromStream(InputStream is) throws IOException { int numLines = 0, numSkipped = 0; Reader decoder = new InputStreamReader(is, "UTF-8"); BufferedReader br = new BufferedReader(decoder); String line = ""; double tmpValue = 0; while ((line = br.readLine()) != null) { // System.out.println(line); line = line.trim(); if (line.charAt(0) != SKIPLINE_CHAR) { try { tmpValue = Double.parseDouble(line); data.add(tmpValue); } catch (NumberFormatException nfe) { System.out.println("Warning: Line " + (numLines + 1) + " in the dataset has been skipped"); System.out.println(line); numSkipped++; } } else { numSkipped++; } numLines++; } } public static void setSkipLineChar(char c) { SKIPLINE_CHAR = c; } public static char getSkipLineChar() { return SKIPLINE_CHAR; } public ArrayList<Double> getSamples() { return data; } public int getSampleSize() { return data.size(); } public Trace getSubTrace(int start, int end) { Trace t = new Trace(); // NOTE: in List.subList the second parameter is exclusive, index starts from 0 t.data = new ArrayList<Double>(data.subList(start, end + 1)); return t; } public double getMin() { return Collections.min(data); } public double getMax() { return Collections.max(data); } public double getAverage() { double sum = 0; Iterator<Double> i = data.iterator(); while (i.hasNext()) { sum += i.next(); } return sum / data.size(); } public double getBound(double coverage) { double ret = 0; forbidSystemExitCall(); try { ret = MonitoringService.getBound(data, coverage, data.size()); } catch (MonitoringServiceException e) { System.out.println(e); } catch (ExitTrappedException e) { ret = Double.NaN; System.out.println(e); } finally { enableSystemExitCall(); } return ret; } public Distribution getDistribution(double coverage) { Distribution d = null; forbidSystemExitCall(); try { PhaseDetectionMechanism m = new MechanismAD_KS(); d = m.getDistribution(data, coverage, data.size()); } catch (MonitoringServiceException e) { System.out.println(e); } catch (ExitTrappedException e) { d = new Distribution(); } finally { enableSystemExitCall(); } return d; } public String getDistributionReadable(double coverage) { return Utils.distributionToString(getDistribution(coverage)); } public CHDistribution[] getPhases(double coverage, int window) { int len = data.size() - (window - 1); CHDistribution[] dArray = new CHDistribution[len]; for (int i = 0; i < len; i++) { try { dArray[i] = CHDistribution.toCHDistribution(getSubTrace(i, i + (window - 1)), coverage); } catch (Exception e) { System.out.println("getSubTrace: " + e.getMessage()); } } return dArray; } public double[] getDynamicBound(double coverage, int window) { int len = data.size() - (window - 1); double bounds[] = new double[len]; for (int i = 0; i < len; i++) { try { bounds[i] = getSubTrace(i, i + (window - 1)).getBound(coverage); } catch (Exception e) { System.out.println("getDynamicBound: " + e.getMessage()); } } return bounds; } public double getValueAt(int index) { return data.get(index); } public boolean hasNegativeValues() { boolean hasNeg = false; Iterator<Double> it = data.iterator(); while (it.hasNext() && !hasNeg) { hasNeg = (hasNeg || it.next() < 0); } return hasNeg; } public Trace[] splitPositiveNegative() { Trace p = new Trace(); Trace n = new Trace(); p.name = name + "+"; n.name = name + "-"; Iterator<Double> it = data.iterator(); Double value = 0.0; while (it.hasNext()) { value = it.next(); if (value >= 0) { p.data.add(value); n.data.add(0.0); } else { p.data.add(0.0); n.data.add(-value); } } return new Trace[] { p, n }; } /** * Checks if the input stream is compressed, and in case it returns a GZIPInputStream * @param stream * @return * @throws IOException */ private static boolean checkGZIP(InputStream stream) throws IOException { PushbackInputStream pb = new PushbackInputStream(stream, 2); //we need a pushbackstream to look ahead byte[] signature = new byte[2]; pb.read(signature); //read the signature pb.unread(signature); //push back the signature to the stream if (signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b) //check if matches standard gzip magic number return true; else return false; } /* This is required to avoid ADAPTARE quit the application with certain inputs */ private static class ExitTrappedException extends SecurityException { } private static void forbidSystemExitCall() { final SecurityManager securityManager = new SecurityManager() { public void checkPermission(Permission permission) { if (permission.getName().contains("exitVM")) { throw new ExitTrappedException(); } } }; System.setSecurityManager(securityManager); } private static void enableSystemExitCall() { System.setSecurityManager(null); } }