diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/Connectivity.java b/Legacy/bonej/src/main/java/org/bonej/plugins/Connectivity.java
index b499099d..12bce74d 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/Connectivity.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/Connectivity.java
@@ -138,7 +138,6 @@ public void run(final String arg) {
ri.setResultInRow(imp, "Connectivity", connectivity);
ri.setResultInRow(imp, "Conn.D (" + imp.getCalibration().getUnit() + "^-3)", connDensity);
ri.updateTable();
- UsageReporter.reportEvent(this).send();
return;
}
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/DeleteSliceRange.java b/Legacy/bonej/src/main/java/org/bonej/plugins/DeleteSliceRange.java
index 5247033e..d3caf299 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/DeleteSliceRange.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/DeleteSliceRange.java
@@ -75,7 +75,6 @@ public void run(final String arg) {
imp.setStack(null, stack);
imp.show();
- UsageReporter.reportEvent(this).send();
}
/**
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/DensityCalibrator.java b/Legacy/bonej/src/main/java/org/bonej/plugins/DensityCalibrator.java
index 6a8a9d6c..f13178d3 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/DensityCalibrator.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/DensityCalibrator.java
@@ -61,7 +61,6 @@ public void run(final String arg) {
IJ.error("Can't calibrate image\n" + e.getMessage());
return;
}
- UsageReporter.reportEvent(this).send();
}
private static void scanco(final ImagePlus imp) throws IllegalArgumentException {
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/Moments.java b/Legacy/bonej/src/main/java/org/bonej/plugins/Moments.java
index 58e722d5..334821c5 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/Moments.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/Moments.java
@@ -220,7 +220,6 @@ public void run(final String arg) {
if (doAxes3D) show3DAxes(imp, E.getV(), centroid, startSlice, endSlice, min,
max);
- UsageReporter.reportEvent(this).send();
}
/**
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/Orienteer.java b/Legacy/bonej/src/main/java/org/bonej/plugins/Orienteer.java
index 90456fcc..ad04b3fb 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/Orienteer.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/Orienteer.java
@@ -243,8 +243,6 @@ public Orienteer() {
if (WindowManager.getImageCount() == 0) return;
final ImagePlus imp = WindowManager.getCurrentImage();
setup(imp);
-
- UsageReporter.reportEvent(this).send();
}
@Override
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/ParticleCounter.java b/Legacy/bonej/src/main/java/org/bonej/plugins/ParticleCounter.java
index 1949a4b1..fb4ee510 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/ParticleCounter.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/ParticleCounter.java
@@ -449,7 +449,6 @@ public void run(final String arg) {
}
IJ.showProgress(1.0);
IJ.showStatus("Particle Analysis Complete");
- UsageReporter.reportEvent(this).send();
}
/**
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/Purify.java b/Legacy/bonej/src/main/java/org/bonej/plugins/Purify.java
index b95cf6a8..9d548f04 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/Purify.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/Purify.java
@@ -99,7 +99,6 @@ public void run(final String arg) {
if (showPerformance) {
showResults(duration, imp);
}
- UsageReporter.reportEvent(this).send();
}
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/ReporterOptions.java b/Legacy/bonej/src/main/java/org/bonej/plugins/ReporterOptions.java
deleted file mode 100644
index b02782cf..00000000
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/ReporterOptions.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*-
- * #%L
- * Mavenized version of the BoneJ1 plugins
- * %%
- * Copyright (C) 2015 - 2023 Michael Doube, BoneJ developers
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
-
-
-package org.bonej.plugins;
-
-import java.util.Random;
-
-import ij.Prefs;
-import ij.gui.GenericDialog;
-import ij.plugin.PlugIn;
-
-public class ReporterOptions implements PlugIn {
-
- static final String OPTOUTSET = "bonej.report.option.set";
- /** Set to false if reporting is not allowed */
- static final String OPTOUTKEY = "bonej.allow.reporter";
- static final String COOKIE = "bonej.report.cookie";
- static final String COOKIE2 = "bonej.report.cookie2";
- static final String FIRSTTIMEKEY = "bonej.report.firstvisit";
- static final String SESSIONKEY = "bonej.report.bonejsession";
- private static final String IJSESSIONKEY = "bonej.report.ijsession";
-
- @Override
- public void run(final String arg) {
-
- final GenericDialog dialog = new GenericDialog("BoneJ");
- dialog.addMessage("Allow usage data collection?");
- dialog.addMessage("BoneJ would like to collect data on \n" +
- "which plugins are being used, to direct development\n" +
- "and promote BoneJ to funders.");
- dialog.addMessage("If you agree to participate please hit OK\n" +
- "otherwise, cancel. For more information click Help.");
- dialog.addHelp("https://imagej.github.io/plugins/bonej#usage-reporting");
- dialog.showDialog();
- if (dialog.wasCanceled()) {
- Prefs.set(OPTOUTKEY, false);
- Prefs.set(COOKIE, "");
- Prefs.set(COOKIE2, "");
- Prefs.set(FIRSTTIMEKEY, "");
- Prefs.set(SESSIONKEY, "");
- Prefs.set(IJSESSIONKEY, "");
- }
- else {
- Prefs.set(OPTOUTKEY, true);
- Prefs.set(COOKIE, new Random().nextInt(Integer.MAX_VALUE));
- Prefs.set(COOKIE2, new Random().nextInt(Integer.MAX_VALUE));
- final long time = System.currentTimeMillis() / 1000;
- Prefs.set(FIRSTTIMEKEY, Long.toString(time));
- Prefs.set(SESSIONKEY, 1);
- }
-
- Prefs.set(OPTOUTSET, true);
- Prefs.savePreferences();
- UsageReporter.reportEvent(this).send();
- }
-}
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/SliceGeometry.java b/Legacy/bonej/src/main/java/org/bonej/plugins/SliceGeometry.java
index 2e28e3d3..b83d7dcb 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/SliceGeometry.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/SliceGeometry.java
@@ -391,7 +391,6 @@ else if (roi.getType() != Roi.RECTANGLE) {
if (do3DAnnotation) {
show3DAxes(imp);
}
- UsageReporter.reportEvent(this).send();
}
private void initOrientationCheckBox(final GenericDialog gd) {
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/SphereFitter.java b/Legacy/bonej/src/main/java/org/bonej/plugins/SphereFitter.java
index b274b832..bfc7ae8d 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/SphereFitter.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/SphereFitter.java
@@ -165,7 +165,6 @@ public void run(final String arg) {
if (doRoiMan) {
addToRoiManager(imp, roiMan, sphereDim, clearRois);
}
- UsageReporter.reportEvent(this).send();
}
/**
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/UsageReporter.java b/Legacy/bonej/src/main/java/org/bonej/plugins/UsageReporter.java
deleted file mode 100644
index e8da269f..00000000
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/UsageReporter.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*-
- * #%L
- * Mavenized version of the BoneJ1 plugins
- * %%
- * Copyright (C) 2015 - 2023 Michael Doube, BoneJ developers
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
-
-
-package org.bonej.plugins;
-
-import java.awt.Dimension;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.Toolkit;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.net.URLConnection;
-import java.nio.charset.Charset;
-import java.util.Locale;
-import java.util.Random;
-
-import org.scijava.util.VersionUtils;
-
-import ij.IJ;
-import ij.Prefs;
-
-/**
- * Prepare and send a report to be logged by Google Analytics event tracking
- *
- * Should be called in a PlugIn's run() method as
- * UsageReporter.reportEvent(this).send()
- *
- *
- * @author Michael Doube
- */
-public final class UsageReporter {
-
- private static final UsageReporter INSTANCE = new UsageReporter();
-
- private static final String ga = "https://www.google-analytics.com/__utm.gif?";
- private static final String utmwv = "utmwv=5.2.5&";
- private static final String utmhn = "utmhn=bonej.org&";
- private static final String utmcs = "utmcs=" + Charset.defaultCharset() + "&";
- private static final String utmac = "utmac=UA-366405-8&";
- private static final String utmdt = "utmdt=bonej.org%20Usage%20Statistics&";
- private static final String utmt = "utmt=event&";
- private static final String utmul = "utmul=" + getLocaleString() + "&";
- private static final String utmje = "utmje=0&";
- private static final String utmfl = "utmfl=11.1%20r102&";
- private static final String utmr = "utmr=-&";
- private static final String utmp = "utmp=%2Fstats&";
- private static final Random random = new Random();
- private static String utmcnr = "";
- private static String utme;
- private static String utmn;
- private static String utmsr;
- private static String utmvp;
- private static String utmsc;
- private static int session = 0;
- private static String utms = "utms=" + session + "&";
- private static String utmcc;
- private static long thisTime = 0;
- private static long lastTime = 0;
- private static String bonejSession = Prefs.get(ReporterOptions.SESSIONKEY,
- Integer.toString(new Random().nextInt(1000)));
- private static String utmhid;
-
- /**
- * Constructor used by singleton pattern. Report variables that relate to
- * single sessions are set here
- */
- private UsageReporter() {
- if (!Prefs.get(ReporterOptions.OPTOUTKEY, false)) return;
- bonejSession = Prefs.get(ReporterOptions.SESSIONKEY, Integer.toString(
- new Random().nextInt(1000)));
- int inc = Integer.parseInt(bonejSession);
- inc++;
- bonejSession = Integer.toString(inc);
- Prefs.set(ReporterOptions.SESSIONKEY, inc);
-
- final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- final GraphicsEnvironment ge = GraphicsEnvironment
- .getLocalGraphicsEnvironment();
- int width = 0;
- int height = 0;
- if (!ge.isHeadlessInstance()) {
- final GraphicsDevice[] screens = ge.getScreenDevices();
- for (final GraphicsDevice screen : screens) {
- final GraphicsConfiguration[] gc = screen.getConfigurations();
- for (final GraphicsConfiguration g : gc) {
- width = Math.max(g.getBounds().x + g.getBounds().width, width);
- height = Math.max(g.getBounds().y + g.getBounds().height, height);
- }
- }
- }
-
- utmsr = "utmsr=" + screenSize.width + "x" + screenSize.height + "&";
- utmvp = "utmvp=" + width + "x" + height + "&";
- utmsc = "utmsc=24-bit&";
- }
-
- /**
- * Send the report to Google Analytics in the form of an HTTP request for a
- * 1-pixel GIF with lots of parameters set
- */
- public void send() {
- if (!isAllowed()) return;
- try {
- final URL url = new URL(ga + utmwv + utms + utmn + utmhn + utmt + utme + utmcs +
- utmsr + utmvp + utmsc + utmul + utmje + utmfl + utmcnr + utmdt +
- utmhid + utmr + utmp + utmac + utmcc);
- final URLConnection uc = url.openConnection();
- uc.setRequestProperty("User-Agent", userAgentString());
- //the next line appears to be necessary to complete the HTTP request
- try (final BufferedReader reader = new BufferedReader(new InputStreamReader(
- uc.getInputStream()))) {
- if (IJ.debugMode) {
- IJ.log(url.toString());
- IJ.log(uc.getRequestProperty("User-Agent"));
- reader.lines().forEach(IJ::log);
- }
- } catch (final IOException e) {
- IJ.error(e.getMessage());
- }
- }
- catch (final IOException e) {
- if (IJ.debugMode) {
- IJ.error(e.getMessage());
- }
- }
- }
-
- /**
- * Sets the instance variables to appropriate values based on the system
- * parameters and method arguments.
- *
- * @param category Google Analytics event category classification
- * @param action Google Analytics event action classification
- * @param label Google Analytics event label classification
- * @param value Google Analytics event value - an integer used for sum and
- * average statistics
- * @return The instance of UsageReporter ready to send() a report
- */
- private static UsageReporter reportEvent(final String category,
- final String action, final String label, final Integer value)
- {
- if (!Prefs.get(ReporterOptions.OPTOUTKEY, false)) return INSTANCE;
- utms = "utms=" + session + "&";
- session++;
- final String val = (value == null) ? "" : "(" + value + ")";
- final String lab = (label == null) ? "" : label;
- utme = "utme=5(" + category + "*" + action + "*" + lab + ")" + val + "&";
- utmn = "utmn=" + random.nextInt(Integer.MAX_VALUE) + "&";
- utmhid = "utmhid=" + random.nextInt(Integer.MAX_VALUE) + "&";
-
- final long time = System.currentTimeMillis() / 1000;
- lastTime = thisTime;
- if (lastTime == 0) lastTime = time;
- thisTime = time;
-
- if ("".equals(utmcnr)) utmcnr = "utmcn=1&";
- else utmcnr = "utmcr=1&";
-
- utmcc = getCookieString();
- return INSTANCE;
- }
-
- /**
- * Prepare the instance for sending a report on a specific class; {@link Class#getName}
- * is added to the 'action' field of the report,
- * category is "Plugin Usage" and label is the version string generated by
- * {@link org.scijava.util.VersionUtils#getVersion}.
- *
- * @param o Class to report on
- * @return The instance of UsageReporter ready to send() a report
- */
- public static UsageReporter reportEvent(final Object o) {
- return reportEvent("Plugin%20Usage", o.getClass().getName(), VersionUtils.getVersion(o.getClass()),
- null);
- }
-
- /**
- * Create a string of cookie data for the gif URL
- *
- * @return cookie string
- */
- private static String getCookieString() {
- // seems to be a bug in Prefs.getInt, so are Strings wrapped in
- // Integer.toString()
- final String cookie = Prefs.get(ReporterOptions.COOKIE, Integer.toString(
- random.nextInt(Integer.MAX_VALUE)));
- final String cookie2 = Prefs.get(ReporterOptions.COOKIE2, Integer.toString(
- random.nextInt(Integer.MAX_VALUE)));
- final String firstTime = Prefs.get(ReporterOptions.FIRSTTIMEKEY, Integer
- .toString(random.nextInt(Integer.MAX_VALUE)));
- // thisTime is not correct, but a best guess
- return "utmcc=__utma%3D" + cookie + "." + cookie2 + "." + firstTime + "." +
- lastTime + "." + thisTime + "." + bonejSession + "%3B%2B__utmz%3D" +
- cookie + "." + thisTime +
- ".79.42.utmcsr%3Dgoogle%7Cutmccn%3D(organic)%7C" +
- "utmcmd%3Dorganic%7Cutmctr%3DBoneJ%20Usage%20Reporter%3B";
- }
-
- private static String getLocaleString() {
- String locale = Locale.getDefault().toString();
- locale = locale.replace("_", "-");
- locale = locale.toLowerCase(Locale.ENGLISH);
- return locale;
- }
-
- private boolean isAllowed() {
- if (!Prefs.get(ReporterOptions.OPTOUTSET, false)) new ReporterOptions().run(
- "");
- return Prefs.get(ReporterOptions.OPTOUTKEY, true);
- }
-
- private static String userAgentString() {
- final String os;
- if (IJ.isMacintosh()) {
- // Handle Mac OSes on PPC and Intel
- String arch = System.getProperty("os.arch");
- if (arch.contains("x86") || arch.contains("i386")) arch = "Intel";
- else if (arch.contains("ppc")) arch = arch.toUpperCase();
- os = "Macintosh; " + arch + " " + System.getProperty("os.name") + " " +
- System.getProperty("os.version");
- }
- else if (IJ.isWindows()) {
- // Handle Windows using the NT version number
- os = "Windows NT " + System.getProperty("os.version");
- }
- else {
- // Handle Linux and everything else
- os = System.getProperty("os.name") + " " + System.getProperty(
- "os.version") + " " + System.getProperty("os.arch");
- }
-
- final String browser = "Java/" + System.getProperty("java.version");
- final String vendor = System.getProperty("java.vendor");
- final String locale = getLocaleString();
-
- return browser + " (" + os + "; " + locale + ") " + vendor;
- }
-}
diff --git a/Legacy/bonej/src/main/java/org/bonej/plugins/VoxelDepthChecker.java b/Legacy/bonej/src/main/java/org/bonej/plugins/VoxelDepthChecker.java
index 357b84d1..00001e59 100644
--- a/Legacy/bonej/src/main/java/org/bonej/plugins/VoxelDepthChecker.java
+++ b/Legacy/bonej/src/main/java/org/bonej/plugins/VoxelDepthChecker.java
@@ -43,6 +43,5 @@ public void run(final String arg) {
final ImagePlus imp = IJ.getImage();
if (null == imp) return;
ImageCheck.dicomVoxelDepth(imp);
- UsageReporter.reportEvent(this).send();
}
}
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/AnalyseSkeletonWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/AnalyseSkeletonWrapper.java
index d7e7de75..0d2925fe 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/AnalyseSkeletonWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/AnalyseSkeletonWrapper.java
@@ -208,7 +208,6 @@ public void run() {
shortestPaths.setCalibration(inputImage.getCalibration());
}
}
- reportUsage();
}
private boolean hasNoSkeletons(final AnalyzeSkeleton_ analyzeSkeleton_) {
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/AnisotropyWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/AnisotropyWrapper.java
index 2bceabb1..10e56337 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/AnisotropyWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/AnisotropyWrapper.java
@@ -217,7 +217,6 @@ public void run() {
}
addResults(subspaces, ellipsoids);
resultsTable = SharedTable.getTable();
- reportUsage();
}
// region -- Helper methods --
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/BoneJCommand.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/BoneJCommand.java
index e7b32c09..94d00bdd 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/BoneJCommand.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/BoneJCommand.java
@@ -38,21 +38,15 @@
import org.bonej.wrapperPlugins.wrapperUtils.Common;
import org.bonej.wrapperPlugins.wrapperUtils.HyperstackUtils;
import org.bonej.wrapperPlugins.wrapperUtils.HyperstackUtils.Subspace;
-import org.bonej.wrapperPlugins.wrapperUtils.UsageReporter;
import org.scijava.ItemIO;
-import org.scijava.command.CommandService;
import org.scijava.command.ContextCommand;
import org.scijava.plugin.Parameter;
-import org.scijava.log.LogService;
-import org.scijava.plugin.PluginService;
-import org.scijava.prefs.PrefService;
import org.scijava.table.DefaultColumn;
import org.scijava.table.Table;
import static java.util.stream.Collectors.toList;
public abstract class BoneJCommand extends ContextCommand {
- private static UsageReporter reporter;
protected List> subspaces;
@@ -71,23 +65,4 @@ protected > List> find3DSubspaces(
final ImgPlus bitImgPlus = Common.toBitTypeImgPlus(opService, image);
return HyperstackUtils.split3DSubspaces(bitImgPlus).collect(toList());
}
-
- protected void reportUsage() {
- if (reporter == null) {
- initReporter();
- }
- reporter.reportEvent(getClass().getName());
- }
-
- private void initReporter() {
- final PrefService prefService = context().getService(PrefService.class);
- final PluginService pluginService = context().getService(PluginService.class);
- final CommandService commandService = context().getService(CommandService.class);
- final LogService logService = context().getService(LogService.class);
- reporter = UsageReporter.getInstance(prefService, pluginService, commandService, logService);
- }
-
- static void setReporter(final UsageReporter reporter) {
- BoneJCommand.reporter = reporter;
- }
}
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ConnectivityWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ConnectivityWrapper.java
index fb4876f3..8216fb8c 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ConnectivityWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ConnectivityWrapper.java
@@ -110,7 +110,6 @@ public void run() {
subspaceConnectivity(label, subspace.interval);
});
resultsTable = SharedTable.getTable();
- reportUsage();
}
private void addResults(final String label, final double eulerCharacteristic,
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ElementFractionWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ElementFractionWrapper.java
index aaf99658..de1be7ba 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ElementFractionWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ElementFractionWrapper.java
@@ -118,7 +118,6 @@ public void run() {
addResults(label, foregroundSize, totalSize, ratio);
}
resultsTable = SharedTable.getTable();
- reportUsage();
}
private void findSubspaces(final ImgPlus inputImage) {
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/EllipsoidFactorWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/EllipsoidFactorWrapper.java
index 80618f31..6f6b2ec0 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/EllipsoidFactorWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/EllipsoidFactorWrapper.java
@@ -317,7 +317,6 @@ public void run() {
}
resultsTable = SharedTable.getTable();
statusService.showStatus("Ellipsoid Factor completed");
- reportUsage();
}
private List divideOutput(final List outputList, final int repetitions) {
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/FitEllipsoidWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/FitEllipsoidWrapper.java
index 1090eafb..40c7130b 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/FitEllipsoidWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/FitEllipsoidWrapper.java
@@ -118,7 +118,6 @@ public void run() {
}
addResults(result.get());
resultsTable = SharedTable.getTable();
- reportUsage();
}
private void addResults(final Ellipsoid ellipsoid) {
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/FractalDimensionWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/FractalDimensionWrapper.java
index 12b73c0b..d1c93f14 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/FractalDimensionWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/FractalDimensionWrapper.java
@@ -171,7 +171,6 @@ public void run() {
});
fillResultsTable(subspaces, dimensions, rSquared);
resultsTable = SharedTable.getTable();
- reportUsage();
}
// region -- Helper methods --
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/IntertrabecularAngleWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/IntertrabecularAngleWrapper.java
index c48d61b3..c0fdc9e0 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/IntertrabecularAngleWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/IntertrabecularAngleWrapper.java
@@ -207,7 +207,6 @@ public void run() {
addResults(radianMap);
printEdgeCentroids(cleanGraph.getEdges());
printCulledEdgePercentages(pruningResult.b);
- reportUsage();
}
private void addResults(final Map anglesMap) {
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SkeletoniseWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SkeletoniseWrapper.java
index dd61eafa..9549472c 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SkeletoniseWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SkeletoniseWrapper.java
@@ -86,7 +86,6 @@ public void run() {
statusService.showStatus("Skeletonise: skeletonising");
skeletoniser.setup("", skeleton);
skeletoniser.run(null);
- reportUsage();
}
@SuppressWarnings("unused")
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SurfaceAreaWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SurfaceAreaWrapper.java
index 265e4951..602a07de 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SurfaceAreaWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SurfaceAreaWrapper.java
@@ -138,7 +138,6 @@ public void run() {
}
calculateAreas(meshes);
resultsTable = SharedTable.getTable();
- reportUsage();
}
/**
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SurfaceFractionWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SurfaceFractionWrapper.java
index 7fe18a30..78a16f62 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SurfaceFractionWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/SurfaceFractionWrapper.java
@@ -108,7 +108,6 @@ public void run() {
statusService.showProgress(i, subspaces.size());
}
resultsTable = SharedTable.getTable();
- reportUsage();
}
// region -- Helper methods --
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ThicknessWrapper.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ThicknessWrapper.java
index d4bb6c70..f5e46009 100644
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ThicknessWrapper.java
+++ b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/ThicknessWrapper.java
@@ -141,7 +141,6 @@ public void run() {
spacingMap.setLut(fire);
}
}
- reportUsage();
}
private void addMapResults(final ImagePlus map) {
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporter.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporter.java
deleted file mode 100644
index e18c448d..00000000
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporter.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*-
- * #%L
- * High-level BoneJ2 commands.
- * %%
- * Copyright (C) 2015 - 2023 Michael Doube, BoneJ developers
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
-
-
-package org.bonej.wrapperPlugins.wrapperUtils;
-
-import java.awt.Dimension;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.Toolkit;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.net.URLConnection;
-import java.nio.charset.Charset;
-import java.util.Locale;
-import java.util.Random;
-import java.util.concurrent.ExecutionException;
-
-import org.scijava.command.CommandModule;
-import org.scijava.command.CommandService;
-import org.scijava.log.Logger;
-import org.scijava.plugin.PluginService;
-import org.scijava.prefs.PrefService;
-
-/**
- * Prepares and sends a report about BoneJ usage to be logged by
- * Google Analytics event tracking
- *
- * @author Michael Doube
- * @author Richard Domander
- */
-// TODO Instead of System.out print debug stuff with LogService
-// TODO Instead of System.out print status messages with StatusService
-// Don't make class final - breaks Mockito
-public class UsageReporter {
-
- private static final String ga = "https://www.google-analytics.com/__utm.gif?";
- private static final String utmwv = "utmwv=5.2.5&";
- private static final String utmhn = "utmhn=bonej.org&";
- private static final String utmcs = "utmcs=" + Charset.defaultCharset() + "&";
- private static final String utmac = "utmac=UA-366405-8&";
- private static final String utmdt = "utmdt=bonej.org%20Usage%20Statistics&";
- private static final String utmt = "utmt=event&";
- private static final String utmul = "utmul=" + getLocaleString() + "&";
- private static final String utmje = "utmje=0&";
- private static final String utmr = "utmr=-&";
- private static final String utmp = "utmp=%2Fstats&";
- private static final Random random = new Random();
- private static String utmcnr = "";
- private static String utmsr;
- private static String utmvp;
- private static String utmsc;
- /** Incremented on each new event */
- private static int session;
- private static long thisTime;
- private static long lastTime;
- private static boolean isFirstRun = true;
- private static PrefService prefs;
- private static PluginService plugins;
- private static CommandService commandService;
- private static UsageReporter instance;
- private static String utms;
- private static String utmn;
- private static String utme;
- private static String utmhid;
- private static String utmcc;
- private static Logger logger;
-
- private UsageReporter() {}
-
- /**
- * Reports a the usage of a plug-in to bonej.org
- *
- * @param className Name of the reporting plug-in's class
- */
- public void reportEvent(final String className) {
- if (!isAllowed()) {
- logger.debug("Usage reporting forbidden by user");
- return;
- }
- final String version = plugins.getPlugin(className).getVersion();
- reportEvent(className, version);
- }
-
- public static UsageReporter getInstance(final PrefService prefs,
- final PluginService plugins, final CommandService commandService, final Logger logger)
- {
- if (prefs == null || plugins == null || commandService == null || logger == null) {
- throw new NullPointerException("Services cannot be null");
- }
- if (instance == null) {
- instance = new UsageReporter();
- }
- UsageReporter.commandService = commandService;
- UsageReporter.plugins = plugins;
- UsageReporter.prefs = prefs;
- UsageReporter.logger = logger;
- return instance;
- }
-
- /**
- * Create a string of cookie data for the gif URL
- *
- * @return cookie string
- */
- private static String getCookieString(final PrefService prefs) {
- final int cookie = prefs.getInt(UsageReporterOptions.class,
- UsageReporterOptions.COOKIE, random.nextInt(Integer.MAX_VALUE));
- final int cookie2 = prefs.getInt(UsageReporterOptions.class,
- UsageReporterOptions.COOKIE2, random.nextInt(Integer.MAX_VALUE));
- final long firstTime = prefs.getInt(UsageReporterOptions.class,
- UsageReporterOptions.FIRSTTIMEKEY, random.nextInt(Integer.MAX_VALUE));
- final int bonejSession = prefs.getInt(UsageReporterOptions.class,
- UsageReporterOptions.SESSIONKEY, 0);
- // thisTime is not correct, but a best guess
- return "utmcc=__utma%3D" + cookie + "." + cookie2 + "." + firstTime + "." +
- lastTime + "." + thisTime + "." + bonejSession + "%3B%2B__utmz%3D" +
- cookie + "." + thisTime +
- ".79.42.utmcsr%3Dgoogle%7Cutmccn%3D(organic)%7C" +
- "utmcmd%3Dorganic%7Cutmctr%3DBoneJ%20Usage%20Reporter%3B";
- }
-
- private static String getLocaleString() {
- String locale = Locale.getDefault().toString();
- locale = locale.replace("_", "-");
- locale = locale.toLowerCase(Locale.ENGLISH);
- return locale;
- }
-
- private static void initSessionVariables(final PrefService prefs) {
- logger.debug("First run of Usage Reporter for this BoneJ session");
- final int bonejSession = prefs.getInt(UsageReporterOptions.class,
- UsageReporterOptions.SESSIONKEY, 0);
- logger.debug("bonejSession = " + bonejSession);
- prefs.put(UsageReporterOptions.class, UsageReporterOptions.SESSIONKEY,
- bonejSession + 1);
- final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- final GraphicsEnvironment ge = GraphicsEnvironment
- .getLocalGraphicsEnvironment();
- int width = 0;
- int height = 0;
- if (!ge.isHeadlessInstance()) {
- final GraphicsDevice[] screens = ge.getScreenDevices();
- for (final GraphicsDevice screen : screens) {
- final GraphicsConfiguration[] gc = screen.getConfigurations();
- for (final GraphicsConfiguration g : gc) {
- width = Math.max(g.getBounds().x + g.getBounds().width, width);
- height = Math.max(g.getBounds().y + g.getBounds().height, height);
- }
- }
- }
- utmsr = "utmsr=" + screenSize.width + "x" + screenSize.height + "&";
- utmvp = "utmvp=" + width + "x" + height + "&";
- utmsc = "utmsc=24-bit&";
- isFirstRun = false;
- }
-
- /**
- * Sets the instance variables to appropriate values based on the system
- * parameters and method arguments and makes the URL request to Google
- *
- * @param action Google Analytics event action classification
- * @param label Google Analytics event label classification
- */
- private static void reportEvent(final String action, final String label) {
- if (isFirstRun) {
- initSessionVariables(prefs);
- }
-
- // set
- utms = "utms=" + session + "&";
- session++;
- utme = "utme=5(" + "Plugin%20Usage" + "*" + action + "*" + label + ")&";
- utmn = "utmn=" + random.nextInt(Integer.MAX_VALUE) + "&";
- utmhid = "utmhid=" + random.nextInt(Integer.MAX_VALUE) + "&";
-
- final long time = System.currentTimeMillis() / 1000;
- lastTime = thisTime;
- if (lastTime == 0) lastTime = time;
- thisTime = time;
-
- if ("".equals(utmcnr)) utmcnr = "utmcn=1&";
- else utmcnr = "utmcr=1&";
-
- utmcc = getCookieString(prefs);
- send();
- }
-
- /**
- * Send the report to Google Analytics in the form of an HTTP request for a
- * 1-pixel GIF with lots of parameters set
- */
- private static void send() {
- logger.debug("Sending report");
- try {
- logger.debug("Usage reporting approved by user, preparing URL");
- final URL url = new URL(ga + utmwv + utms + utmn + utmhn + utmt + utme + utmcs +
- utmsr + utmvp + utmsc + utmul + utmje + utmcnr + utmdt + utmhid + utmr +
- utmp + utmac + utmcc);
- final URLConnection uc = url.openConnection();
- uc.setRequestProperty("User-Agent", userAgentString());
- logReport(url, uc);
- }
- catch (final IOException e) {
- logger.trace(e.getMessage());
- }
- }
-
- private static void logReport(final URL url, final URLConnection uc) {
- logger.debug(url);
- logger.debug(uc.getRequestProperty("User-Agent"));
- try (final BufferedReader reader = new BufferedReader(new InputStreamReader(
- uc.getInputStream())))
- {
- reader.lines().forEach(line -> logger.debug(line));
- }
- catch (final IOException e) {
- logger.trace(e.getMessage());
- }
- }
-
- private static String userAgentString() {
- final String os;
- final String osName = System.getProperty("os.name");
- final boolean isWin = osName.startsWith("Windows");
- final boolean isMac = !isWin && osName.startsWith("Mac");
- if (isMac) {
- // Handle Mac OSes on PPC and Intel
- String arch = System.getProperty("os.arch");
- if (arch.contains("x86") || arch.contains("i386")) arch = "Intel";
- else if (arch.contains("ppc")) arch = arch.toUpperCase();
- os = "Macintosh; " + arch + " " + System.getProperty("os.name") + " " +
- System.getProperty("os.version");
- }
- else if (isWin) {
- // Handle Windows using the NT version number
- os = "Windows NT " + System.getProperty("os.version");
- }
- else {
- // Handle Linux and everything else
- os = osName + " " + System.getProperty("os.version") + " " + System
- .getProperty("os.arch");
- }
-
- final String browser = "Java/" + System.getProperty("java.version");
- final String vendor = System.getProperty("java.vendor");
- final String locale = getLocaleString();
-
- return browser + " (" + os + "; " + locale + ") " + vendor;
- }
-
- /**
- * Check whether user has given permission to collect usage data
- *
- * @return true only if the user has given explicit permission to send usage
- * data
- */
- boolean isAllowed() {
- final boolean permissionSought = prefs.getBoolean(
- UsageReporterOptions.class, UsageReporterOptions.OPTINSET, false);
- if (!permissionSought) {
- logger.debug("User permission has not been sought, requesting it...");
- try {
- final CommandModule module = commandService.run(
- UsageReporterOptions.class, true).get();
- if (module.isCanceled()) {
- return false;
- }
- }
- catch (final InterruptedException | ExecutionException e) {
- logger.trace(e);
- return false;
- }
- }
- return prefs.getBoolean(UsageReporterOptions.class,
- UsageReporterOptions.OPTINKEY, false);
- }
-}
diff --git a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporterOptions.java b/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporterOptions.java
deleted file mode 100644
index 25b058f5..00000000
--- a/Modern/wrapperPlugins/src/main/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporterOptions.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*-
- * #%L
- * High-level BoneJ2 commands.
- * %%
- * Copyright (C) 2015 - 2023 Michael Doube, BoneJ developers
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
-
-
-package org.bonej.wrapperPlugins.wrapperUtils;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.Random;
-
-import org.scijava.ItemVisibility;
-import org.scijava.command.Command;
-import org.scijava.command.CommandService;
-import org.scijava.command.ContextCommand;
-import org.scijava.log.LogService;
-import org.scijava.platform.PlatformService;
-import org.scijava.plugin.Parameter;
-import org.scijava.plugin.Plugin;
-import org.scijava.plugin.PluginService;
-import org.scijava.prefs.PrefService;
-import org.scijava.ui.UIService;
-import org.scijava.widget.Button;
-
-/**
- * Handles persistent settings such as user permission state. Preferences are
- * stored in their native format (long, int, boolean, etc.)
- *
- * @author Michael Doube
- * @author Richard Domander
- */
-@Plugin(type = Command.class, menuPath = "Edit>Options>BoneJ Usage (Modern)")
-public class UsageReporterOptions extends ContextCommand {
-
- /** set to true if user permission has been requested */
- static final String OPTINSET = "bonej2.report.option.set";
- /** Set to false if reporting is not allowed */
- static final String OPTINKEY = "bonej2.allow.reporter";
- static final String COOKIE = "bonej2.report.cookie";
- static final String COOKIE2 = "bonej2.report.cookie2";
- /** time of first visit in seconds */
- static final String FIRSTTIMEKEY = "bonej2.report.firstvisit";
- /** unique ID for this particular BoneJ session */
- static final String SESSIONKEY = "bonej2.report.bonejsession";
- private static final String IJSESSIONKEY = "bonej2.report.ijsession";
- // TODO Make into one string (format with HTML)
- @Parameter(visibility = ItemVisibility.MESSAGE, persist = false)
- private String message1 = "Allow usage data collection?";
- @Parameter(visibility = ItemVisibility.MESSAGE, persist = false)
- private String message2 = "BoneJ would like to collect data on";
- @Parameter(visibility = ItemVisibility.MESSAGE, persist = false)
- private String message3 =
- "which plugins are being used, to direct development";
- @Parameter(visibility = ItemVisibility.MESSAGE, persist = false)
- private String message4 = "and promote BoneJ to funders.";
- @Parameter(visibility = ItemVisibility.MESSAGE, persist = false)
- private String message5 = "If you agree to participate please check the box.";
- @Parameter(label = "Opt in to usage data collection",
- description = "Can BoneJ send usage data?", persistKey = OPTINKEY)
- private boolean optIn;
- @Parameter(visibility = ItemVisibility.MESSAGE, persist = false)
- private String helpMessage = "For more information click Help.";
- @Parameter(label = "Help", description = "More about data collection", callback = "showHelpPage")
- private Button button;
- @Parameter
- private PrefService prefs;
- @Parameter
- private LogService logService;
- @Parameter
- private PluginService pluginService;
- @Parameter
- private CommandService commandService;
- @Parameter
- private UIService uiService;
- @Parameter
- private PlatformService platformService;
- private UsageReporter reporter;
-
- @Override
- public void run() {
- if (!optIn) {
- // Wipe persistent data on opt-out
- logService.debug("User has opted out of data collection\n");
- prefs.clear(getClass());
- prefs.put(getClass(), OPTINSET, true);
- return;
- }
-
- logService.debug("User has opted in to data collection\n");
- prefs.put(getClass(), OPTINKEY, true);
- prefs.put(getClass(), COOKIE, new Random().nextInt(Integer.MAX_VALUE));
- prefs.put(getClass(), COOKIE2, new Random().nextInt(Integer.MAX_VALUE));
- prefs.put(getClass(), FIRSTTIMEKEY, System.currentTimeMillis() / 1000);
- prefs.put(getClass(), SESSIONKEY, 1);
- prefs.put(getClass(), IJSESSIONKEY, 1);
- prefs.put(getClass(), OPTINSET, true);
- if (reporter == null) {
- reporter = UsageReporter.getInstance(prefs, pluginService, commandService, logService);
- }
- reporter.reportEvent(getClass().getName());
- }
-
- @SuppressWarnings("unused")
- private void showHelpPage() {
- try {
- platformService.open(new URL("https://imagej.github.io/plugins/bonej#usage-reporting"));
- } catch (final IOException e) {
- uiService.showDialog("Something went wrong while opening the help page. Please try again.");
- logService.trace(e);
- }
- }
-}
diff --git a/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/AbstractWrapperTest.java b/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/AbstractWrapperTest.java
index 9f072c3d..3aa95436 100644
--- a/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/AbstractWrapperTest.java
+++ b/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/AbstractWrapperTest.java
@@ -31,7 +31,6 @@
import net.imagej.ImageJ;
import org.bonej.utilities.SharedTable;
-import org.bonej.wrapperPlugins.wrapperUtils.UsageReporter;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -53,7 +52,6 @@
*/
public abstract class AbstractWrapperTest {
private static ImageJ imageJ;
- protected static final UsageReporter MOCK_REPORTER = mock(UsageReporter.class);
protected static final UserInterface MOCK_UI = mock(UserInterface.class);
private static CommandService commandService;
@@ -69,26 +67,22 @@ protected static ImageJ imageJ() {
public static void basicOneTimeSetup() {
imageJ = new ImageJ();
commandService = imageJ.command();
- BoneJCommand.setReporter(MOCK_REPORTER);
}
@Before
public void setup() {
imageJ.ui().setHeadless(false);
imageJ.ui().setDefaultUI(MOCK_UI);
- doNothing().when(MOCK_REPORTER).reportEvent(anyString());
}
@After
public void tearDown() {
Mockito.reset(MOCK_UI);
- Mockito.reset(MOCK_REPORTER);
SharedTable.reset();
}
@AfterClass
public static void basicOneTimeTearDown() {
- BoneJCommand.setReporter(null);
imageJ.context().dispose();
imageJ = null;
commandService = null;
diff --git a/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/AnalyseSkeletonWrapperTest.java b/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/AnalyseSkeletonWrapperTest.java
index 669c8009..5c5b25f3 100644
--- a/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/AnalyseSkeletonWrapperTest.java
+++ b/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/AnalyseSkeletonWrapperTest.java
@@ -41,17 +41,14 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import ij.IJ;
import ij.ImagePlus;
import ij.gui.NewImage;
import ij.measure.Calibration;
-import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
@@ -372,7 +369,6 @@ public void testCancelledRunDoesNotReport() throws ExecutionException,
// VERIFY
assertTrue("Sanity check failed: method didn't cancel", module
.isCanceled());
- verify(MOCK_REPORTER, timeout(1000).times(0)).reportEvent(anyString());
}
@Test
@@ -390,6 +386,5 @@ public void testSuccessfulRunReports() throws ExecutionException,
// VERIFY
assertFalse("Sanity check failed: method cancelled", module.isCanceled());
- verify(MOCK_REPORTER, timeout(1000)).reportEvent(anyString());
}
}
diff --git a/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/EllipsoidFactorWrapperTest.java b/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/EllipsoidFactorWrapperTest.java
index 65d76281..1309b035 100644
--- a/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/EllipsoidFactorWrapperTest.java
+++ b/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/EllipsoidFactorWrapperTest.java
@@ -30,9 +30,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
import net.imagej.axis.Axes;
import net.imagej.axis.DefaultLinearAxis;
@@ -102,7 +99,6 @@ public void testCancelledRunDoesNotReport() throws ExecutionException,
final String reason = module.getCancelReason();
assertEquals("EF should have cancelled because there are no ellipsoids in an empty image",
EllipsoidFactorWrapper.NO_ELLIPSOIDS_FOUND, reason);
- verify(MOCK_REPORTER, timeout(1000).times(0)).reportEvent(anyString());
}
// run(nvectors=100 vectorincrement=0.435 skipratio=1 contactsensitivity=1 maxiterations=100 maxdrift=1.73 minimumsemiaxis=1.0 runs=1 weightedaveragen=1 seedondistanceridge=true distancethreshold=0.6 seedontopologypreserving=false);
@@ -124,7 +120,6 @@ public void testSuccessfulRunReports() throws ExecutionException, InterruptedExc
false).get();
assertFalse("Sanity check failed: method cancelled", module.isCanceled());
- verify(MOCK_REPORTER, timeout(1000)).reportEvent(anyString());
}
@Test
@@ -142,7 +137,6 @@ public void testImgToByteArray(){
@BeforeClass
public static void oneTimeSetup() {
- EllipsoidFactorWrapper.setReporter(MOCK_REPORTER);
}
private static Img createSphereImg() {
diff --git a/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporterTest.java b/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporterTest.java
deleted file mode 100644
index 74a7ab82..00000000
--- a/Modern/wrapperPlugins/src/test/java/org/bonej/wrapperPlugins/wrapperUtils/UsageReporterTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*-
- * #%L
- * High-level BoneJ2 commands.
- * %%
- * Copyright (C) 2015 - 2023 Michael Doube, BoneJ developers
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
-
-package org.bonej.wrapperPlugins.wrapperUtils;
-
-import static org.bonej.wrapperPlugins.wrapperUtils.UsageReporterOptions.OPTINKEY;
-import static org.bonej.wrapperPlugins.wrapperUtils.UsageReporterOptions.OPTINSET;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-import org.bonej.wrapperPlugins.SlowWrapperTest;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.scijava.command.CommandModule;
-import org.scijava.command.CommandService;
-import org.scijava.log.LogService;
-import org.scijava.plugin.PluginService;
-import org.scijava.prefs.PrefService;
-
-/**
- * Tests for {@link UsageReporter}.
- *
- * @author Richard Domander
- */
-public class UsageReporterTest {
-
- @Category(SlowWrapperTest.class)
- @Test
- public void testIsAllowedOptInFalse() {
- // SETUP
- final PrefService prefs = mock(PrefService.class);
- when(prefs.getBoolean(UsageReporterOptions.class, OPTINSET, false))
- .thenReturn(true);
- when(prefs.getBoolean(UsageReporterOptions.class, OPTINKEY, false))
- .thenReturn(false);
- final PluginService plugins = mock(PluginService.class);
- final CommandService commands = mock(CommandService.class);
- final LogService logger = mock(LogService.class);
- final UsageReporter reporter = UsageReporter.getInstance(prefs, plugins, commands, logger);
-
- // EXECUTE
- final boolean allowed = reporter.isAllowed();
-
- // VERIFY
- // OPTINSET save data should been queried
- verify(prefs, timeout(1000)).getBoolean(UsageReporterOptions.class,
- OPTINSET, false);
- // OPTINKEY save data should been queried
- verify(prefs, timeout(1000)).getBoolean(UsageReporterOptions.class,
- OPTINKEY, false);
- assertFalse(allowed);
- }
-
- @Category(SlowWrapperTest.class)
- @Test
- public void testIsAllowedOptInTrue() {
- // SETUP
- final PrefService prefs = mock(PrefService.class);
- when(prefs.getBoolean(UsageReporterOptions.class, OPTINSET, false))
- .thenReturn(true);
- when(prefs.getBoolean(UsageReporterOptions.class, OPTINKEY, false))
- .thenReturn(true);
- final PluginService plugins = mock(PluginService.class);
- final CommandService commands = mock(CommandService.class);
- final LogService logger = mock(LogService.class);
- final UsageReporter reporter = UsageReporter.getInstance(prefs, plugins, commands, logger);
-
- // EXECUTE
- final boolean allowed = reporter.isAllowed();
-
- // VERIFY
- // OPTINSET save data should been queried
- verify(prefs, timeout(1000)).getBoolean(UsageReporterOptions.class,
- OPTINSET, false);
- // OPTINKEY save data should been queried
- verify(prefs, timeout(1000)).getBoolean(UsageReporterOptions.class,
- OPTINKEY, false);
- assertTrue(allowed);
- }
-
- @Category(SlowWrapperTest.class)
- @Test
- public void testIsAllowedPermissionNotSought() throws ExecutionException,
- InterruptedException
- {
- // SETUP
- final PrefService prefs = mock(PrefService.class);
- when(prefs.getBoolean(UsageReporterOptions.class, OPTINSET, false))
- .thenReturn(false);
- when(prefs.getBoolean(UsageReporterOptions.class, OPTINKEY, false))
- .thenReturn(false);
- final PluginService plugins = mock(PluginService.class);
- @SuppressWarnings("unchecked")
- final Future future = mock(Future.class);
- final CommandModule module = mock(CommandModule.class);
- when(module.isCanceled()).thenReturn(false);
- when(future.get()).thenReturn(module);
- final CommandService commands = mock(CommandService.class);
- when(commands.run(UsageReporterOptions.class, true)).thenReturn(future);
- final LogService logger = mock(LogService.class);
- final UsageReporter reporter = UsageReporter.getInstance(prefs, plugins, commands, logger);
-
- // EXECUTE
- final boolean allowed = reporter.isAllowed();
-
- // VERIFY
- // UsageReporterOptions should have been run
- verify(commands, timeout(1000)).run(UsageReporterOptions.class, true);
- // OPTINSET save data should been queried
- verify(prefs, timeout(1000)).getBoolean(UsageReporterOptions.class,
- OPTINSET, false);
- // OPTINKEY save data should been queried
- verify(prefs, timeout(1000)).getBoolean(UsageReporterOptions.class,
- OPTINKEY, false);
- assertFalse(allowed);
- }
-
- @Test
- public void testIsAllowedPermissionSought() throws ExecutionException,
- InterruptedException
- {
- // SETUP
- final PrefService prefs = mock(PrefService.class);
- when(prefs.getBoolean(UsageReporterOptions.class, OPTINSET, false))
- .thenReturn(true);
- when(prefs.getBoolean(UsageReporterOptions.class, OPTINKEY, false))
- .thenReturn(false);
- final PluginService plugins = mock(PluginService.class);
- @SuppressWarnings("unchecked")
- final Future future = mock(Future.class);
- final CommandModule module = mock(CommandModule.class);
- when(module.isCanceled()).thenReturn(false);
- when(future.get()).thenReturn(module);
- final CommandService commands = mock(CommandService.class);
- when(commands.run(UsageReporterOptions.class, true)).thenReturn(future);
- final LogService logger = mock(LogService.class);
- final UsageReporter reporter = UsageReporter.getInstance(prefs, plugins, commands, logger);
-
- // EXECUTE
- reporter.isAllowed();
-
- // VERIFY
- // UsageReporterOptions should not have been run
- verify(commands, timeout(1000).times(0)).run(UsageReporterOptions.class,
- true);
- }
-}