package net.obnoxint.mcdev.omclib.metrics; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashMap; import java.util.Map; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import net.obnoxint.mcdev.feature.Feature; import net.obnoxint.mcdev.omclib.ImplementedFeature; import net.obnoxint.mcdev.omclib.OmcLibPlugin; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; public final class OmcLibMetricsFeature implements Feature { private static final String FEATURE_FOLDER_NAME = "metrics"; private static final String INSTANCE_FILE_EXTENSION = ".dat"; private static final long TASK_DELAY = 0; private static final long TASK_PERIOD = 1200; private final MetricsAdapter adapter; private final OmcLibMetricsProperties properties; private final Map<String, MetricsInstance> metricsInstances = new HashMap<>(); private boolean active = false; private int taskId = -1; private File featureFolder = null; public OmcLibMetricsFeature() { this.adapter = new MetricsAdapter(this); this.properties = new OmcLibMetricsProperties(this); } @Override public String getFeatureName() { return ImplementedFeature.METRICS.getName(); } @Override public Plugin getFeaturePlugin() { return OmcLibPlugin.getInstance(); } @Override public OmcLibMetricsProperties getFeatureProperties() { return properties; } public String getGuid() { return adapter.getGuid(); } public long getLastReportDate() { return adapter.getLastReportDate(); } public synchronized MetricsInstance getMetricsInstance(final Plugin plugin) { final String n = plugin.getName(); if (!metricsInstances.containsKey(n)) { loadInstanceFile(plugin); } return metricsInstances.get(n); } @Override public boolean isFeatureActive() { return active; } @Override public void setFeatureActive(final boolean active) { if (this.active != active) { if (active) { properties.load(); taskId = Bukkit.getScheduler().scheduleAsyncRepeatingTask(getFeaturePlugin(), adapter, TASK_DELAY, TASK_PERIOD); } else { Bukkit.getScheduler().cancelTask(taskId); try { adapter.report(true); } catch (final Exception e) { OmcLibPlugin.getInstance().getLogger().warning(getFeatureName() + ": An exception was thrown while sending a report: " + e.getMessage()); } properties.store(); storeAllInstanceFiles(); } this.active = active; } } File getFeatureFolder() { if (featureFolder == null) { featureFolder = new File(getFeaturePlugin().getDataFolder(), FEATURE_FOLDER_NAME); if (!featureFolder.exists()) { featureFolder.mkdirs(); } } return featureFolder; } synchronized Map<String, MetricsInstance> getMetricsInstances() { return new HashMap<>(metricsInstances); } private void loadInstanceFile(final Plugin plugin) { final String n = plugin.getName(); final File f = new File(getFeatureFolder(), n + INSTANCE_FILE_EXTENSION); if (f.exists()) { ObjectInputStream ois = null; try { ois = new ObjectInputStream(new GZIPInputStream(new FileInputStream(f))); metricsInstances.put(n, (MetricsInstance) ois.readObject()); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } try { ois.close(); } catch (NullPointerException | IOException e) { e.printStackTrace(); } } else { try { f.createNewFile(); } catch (final IOException e) { e.printStackTrace(); } metricsInstances.put(n, new MetricsInstance(plugin)); storeInstanceFile(n); } } private void storeAllInstanceFiles() { for (final String n : metricsInstances.keySet()) { storeInstanceFile(n); } } private void storeInstanceFile(final String n) { final File f = new File(getFeatureFolder(), n + INSTANCE_FILE_EXTENSION); final MetricsInstance mi = new MetricsInstance(metricsInstances.get(n)); final String[] graphs = mi.getGraphNames(); for (final String gn : graphs) { final MetricsGraph graph = mi.getGraph(gn); final String[] plotters = graph.getPlotterIds(); for (final String pid : plotters) { final MetricsPlotter plotter = graph.getPlotter(pid); if (!plotter.isPersistent()) { graph.removePlotter(plotter); } } mi.updateGraph(graph); } try (final ObjectOutputStream ous = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(f)))) { ous.writeObject(mi); ous.flush(); ous.close(); } catch (final IOException e) { e.printStackTrace(); } } }