diff --git a/BootstrapIvy.xml b/BootstrapIvy.xml
index 031c1f2cf3..c668d480ba 100644
--- a/BootstrapIvy.xml
+++ b/BootstrapIvy.xml
@@ -15,7 +15,7 @@
-
diff --git a/Core/build.xml b/Core/build.xml
index 0e5c90ef04..5d91ade7e1 100644
--- a/Core/build.xml
+++ b/Core/build.xml
@@ -74,6 +74,7 @@
+
diff --git a/Core/ivysettings.xml b/Core/ivysettings.xml
index 7a4d38c65e..c27e095ddb 100644
--- a/Core/ivysettings.xml
+++ b/Core/ivysettings.xml
@@ -2,7 +2,7 @@
-
+
diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties
index c01abc4855..94dffdeb9b 100644
--- a/Core/nbproject/project.properties
+++ b/Core/nbproject/project.properties
@@ -120,6 +120,7 @@ file.reference.okhttp-2.7.5-javadoc.jar=release/modules/ext/okhttp-2.7.5-javadoc
file.reference.okhttp-2.7.5-sources.jar=release/modules/ext/okhttp-2.7.5-sources.jar
file.reference.okhttp-2.7.5.jar=release/modules/ext/okhttp-2.7.5.jar
file.reference.okio-1.6.0.jar=release/modules/ext/okio-1.6.0.jar
+file.reference.datcon.jar=release/modules/ext/DatCon.jar
javac.source=1.8
javac.compilerargs=-Xlint -Xlint:-serial
license.file=../LICENSE-2.0.txt
diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml
index 743b58e965..c3f58c1ec6 100644
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -803,6 +803,10 @@
ext/jutf7-1.0.0.jar
release/modules/ext/jutf7-1.0.0.jar
+
+
+ ext/DatCon.jar
+ release/modules/ext/DatCon.jar
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ModuleSettings.java b/Core/src/org/sleuthkit/autopsy/coreutils/ModuleSettings.java
index 7f874395e3..39fec3d161 100644
--- a/Core/src/org/sleuthkit/autopsy/coreutils/ModuleSettings.java
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/ModuleSettings.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011 Basis Technology Corp.
+ * Copyright 2012-2020 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,6 +23,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@@ -30,47 +31,57 @@ import java.util.Set;
import java.util.logging.Level;
/**
- * This class contains the framework to read, add, update, and remove from the
- * property files located at %USERDIR%/Config/x.properties
+ * Provides utility methods for creating, updating, and deleting Java properties
+ * files with paths such as %USERDIR%/Config/[module name].properties, where
+ * "module name" is intended to be a module name and the properties file is
+ * intended to be a settings file for the module.
+ *
+ * Very coarse-grained thread safety is provided by these utilities if all
+ * modules confine themselves to their use when manipulating their settings
+ * files, with the consequence of serializing all such operations across the
+ * entire application.
+ *
+ * TODO (JIRA-5964): The error handling in this class is not consistent with
+ * Autopsy error handling policy.
*/
public class ModuleSettings {
- // The directory where the properties file is located
- private final static String moduleDirPath = PlatformUtil.getUserConfigDirectory();
+ private final static Logger logger = Logger.getLogger(ModuleSettings.class.getName());
+ private final static String MODULE_DIR_PATH = PlatformUtil.getUserConfigDirectory();
+ private final static String SETTINGS_FILE_EXT = ".properties";
+
+ /*
+ * These SHOULD NOT be public and DO NOT belong in this file. They are being
+ * retained only for the sake of backwards compatibility.
+ */
public static final String DEFAULT_CONTEXT = "GeneralContext"; //NON-NLS
public static final String MAIN_SETTINGS = "Case"; //NON-NLS
public static final String CURRENT_CASE_TYPE = "Current_Case_Type"; //NON-NLS
/**
- * the constructor
- */
- private ModuleSettings() {
- }
-
- /**
- * Makes a new config file of the specified name. Do not include the
- * extension.
+ * Makes a new settings file for a module.
*
- * @param moduleName - The name of the config file to make
+ * @param moduleName The module name.
*
- * @return True if successfully created, false if already exists or an error
- * is thrown.
+ * @return True if the settings file was created, false if the file already
+ * existed or could not be created.
*/
- public static boolean makeConfigFile(String moduleName) {
+ public static synchronized boolean makeConfigFile(String moduleName) {
if (!configExists(moduleName)) {
- File propPath = new File(moduleDirPath + File.separator + moduleName + ".properties");
+ File propPath = new File(getSettingsFilePath(moduleName));
File parent = new File(propPath.getParent());
if (!parent.exists()) {
parent.mkdirs();
}
+
Properties props = new Properties();
try {
propPath.createNewFile();
- FileOutputStream fos = new FileOutputStream(propPath);
- props.store(fos, "");
- fos.close();
- } catch (IOException e) {
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.WARNING, "Was not able to create a new properties file.", e); //NON-NLS
+ try (FileOutputStream fos = new FileOutputStream(propPath)) {
+ props.store(fos, "Created module settings file");
+ }
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, String.format("Failed to create module settings file at %s)", propPath), ex); //NON-NLS
return false;
}
return true;
@@ -79,213 +90,217 @@ public class ModuleSettings {
}
/**
- * Determines if a given properties file exists or not.
+ * Indicates whether or not a settings file exists for a given module.
*
- * @param moduleName - The name of the config file to evaluate
+ * @param moduleName The module name.
*
- * @return true if the config exists, false otherwise.
+ * @return True or false.
*/
- public static boolean configExists(String moduleName) {
- File f = new File(moduleDirPath + File.separator + moduleName + ".properties");
- return f.exists();
+ public static synchronized boolean configExists(String moduleName) {
+ return new File(getSettingsFilePath(moduleName)).exists();
}
- public static boolean settingExists(String moduleName, String settingName) {
+ /**
+ * Determines whether or not a given setting exists in the settings file for
+ * a module.
+ *
+ * @param moduleName The module name.
+ * @param settingName The name of the setting (property).
+ *
+ * @return True if the setting file exists, can be read, and contains the
+ * specified setting (property), false otherwise.
+ */
+ public static synchronized boolean settingExists(String moduleName, String settingName) {
if (!configExists(moduleName)) {
return false;
}
+
try {
Properties props = fetchProperties(moduleName);
return (props.getProperty(settingName) != null);
- } catch (IOException e) {
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, String.format("Failed to get %s setting from module settings file at %s)", settingName, getSettingsFilePath(moduleName)), ex); //NON-NLS
return false;
}
-
}
/**
- * Returns the path of the given properties file.
+ * Constructs a settings file path for a given module.
*
- * @param moduleName - The name of the config file to evaluate
+ * @param moduleName The module name.
*
- * @return The path of the given config file. Returns null if the config
- * file doesn't exist.
+ * @return The settings file path as a string.
*/
- private static String getPropertyPath(String moduleName) {
- if (configExists(moduleName)) {
- return moduleDirPath + File.separator + moduleName + ".properties"; //NON-NLS
- }
-
- return null;
+ private static String getSettingsFilePath(String moduleName) {
+ return Paths.get(MODULE_DIR_PATH, moduleName + SETTINGS_FILE_EXT).toString();
}
/**
- * Returns the given properties file's setting as specific by settingName.
+ * Gets the value of a setting (property) from a module settings file.
*
- * @param moduleName - The name of the config file to read from.
- * @param settingName - The setting name to retrieve.
+ * NOTE: If the settings file does not already exist, it is created.
*
- * @return - the value associated with the setting.
+ * @param moduleName The module name.
+ * @param settingName The setting name.
*
- * @throws IOException
+ * @return The value of the setting or null if the file cannot be read or
+ * the setting is not found.
*/
- public static String getConfigSetting(String moduleName, String settingName) {
+ public static synchronized String getConfigSetting(String moduleName, String settingName) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
-
+
try {
Properties props = fetchProperties(moduleName);
-
return props.getProperty(settingName);
- } catch (IOException e) {
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.WARNING, "Could not read config file [" + moduleName + "]", e); //NON-NLS
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, String.format("Failed to get %s setting from module settings file at %s)", settingName, getSettingsFilePath(moduleName)), ex); //NON-NLS
return null;
}
-
}
/**
- * Returns the given properties file's map of settings.
+ * Gets the settings (properties) from a module settings file.
*
- * @param moduleName - the name of the config file to read from.
+ * NOTE: If the settings file does not already exist, it is created.
*
- * @return - the map of all key:value pairs representing the settings of the
- * config.
+ * @param moduleName The module name.
*
- * @throws IOException
+ * @return A mapping of setting names to setting values from the settings
+ * file, may be empty.
*/
- public static Map< String, String> getConfigSettings(String moduleName) {
-
+ public static synchronized Map getConfigSettings(String moduleName) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
+
try {
Properties props = fetchProperties(moduleName);
-
Set keys = props.stringPropertyNames();
- Map map = new HashMap();
-
+ Map map = new HashMap<>();
for (String s : keys) {
map.put(s, props.getProperty(s));
}
-
return map;
- } catch (IOException e) {
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.WARNING, "Could not read config file [" + moduleName + "]", e); //NON-NLS
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, String.format("Failed to get settings from module settings file at %s)", getSettingsFilePath(moduleName)), ex); //NON-NLS
return null;
}
}
/**
- * Sets the given properties file to the given setting map.
+ * Adds a mapping of setting name to setting values to a module settings
+ * file.
*
- * @param moduleName - The name of the module to be written to.
- * @param settings - The mapping of all key:value pairs of settings to add
- * to the config.
+ * NOTE: If the settings file does not already exist, it is created.
+ *
+ * @param moduleName The module name.
+ * @param settings The module settings.
*/
public static synchronized void setConfigSettings(String moduleName, Map settings) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
+
try {
Properties props = fetchProperties(moduleName);
-
for (Map.Entry kvp : settings.entrySet()) {
props.setProperty(kvp.getKey(), kvp.getValue());
}
-
- File path = new File(getPropertyPath(moduleName));
- FileOutputStream fos = new FileOutputStream(path);
- props.store(fos, "Changed config settings(batch)"); //NON-NLS
- fos.close();
- } catch (IOException e) {
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.WARNING, "Property file exists for [" + moduleName + "] at [" + getPropertyPath(moduleName) + "] but could not be loaded.", e); //NON-NLS NON-NLS NON-NLS
+
+ File path = new File(getSettingsFilePath(moduleName));
+ try (FileOutputStream fos = new FileOutputStream(path)) {
+ props.store(fos, "Set settings (batch)"); //NON-NLS
+ }
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, String.format("Error writing to module settings file at %s)", getSettingsFilePath(moduleName)), ex); //NON-NLS
}
}
/**
- * Sets the given properties file to the given settings.
+ * Sets the value of a setting (property) in a module settings file.
*
- * @param moduleName - The name of the module to be written to.
- * @param settingName - The name of the setting to be modified.
- * @param settingVal - the value to set the setting to.
+ * NOTE: If the settings file does not already exist, it is created.
+ *
+ * @param moduleName The module name.
+ * @param settingName The setting name.
+ * @param settingVal The setting value.
*/
public static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal) {
if (!configExists(moduleName)) {
makeConfigFile(moduleName);
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.INFO, "File did not exist. Created file [" + moduleName + ".properties]"); //NON-NLS NON-NLS
}
-
try {
Properties props = fetchProperties(moduleName);
-
props.setProperty(settingName, settingVal);
-
- File path = new File(getPropertyPath(moduleName));
- FileOutputStream fos = new FileOutputStream(path);
- props.store(fos, "Changed config settings(single)"); //NON-NLS
- fos.close();
- } catch (IOException e) {
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.WARNING, "Property file exists for [" + moduleName + "] at [" + getPropertyPath(moduleName) + "] but could not be loaded.", e); //NON-NLS NON-NLS NON-NLS
- }
- }
-
- /**
- * Removes the given key from the given properties file.
- *
- * @param moduleName - The name of the properties file to be modified.
- * @param key - the name of the key to remove.
- */
- public static synchronized void removeProperty(String moduleName, String key) {
- try {
- if (getConfigSetting(moduleName, key) != null) {
- Properties props = fetchProperties(moduleName);
-
- props.remove(key);
- File path = new File(getPropertyPath(moduleName));
- FileOutputStream fos = new FileOutputStream(path);
- props.store(fos, "Removed " + key); //NON-NLS
- fos.close();
+ File path = new File(getSettingsFilePath(moduleName));
+ try (FileOutputStream fos = new FileOutputStream(path)) {
+ props.store(fos, "Set " + settingName); //NON-NLS
}
- } catch (IOException e) {
- Logger.getLogger(ModuleSettings.class.getName()).log(Level.WARNING, "Could not remove property from file, file not found", e); //NON-NLS
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, String.format("Error writing %s setting to module settings file at %s)", settingName, getSettingsFilePath(moduleName)), ex); //NON-NLS
}
}
/**
- * Returns the properties file as specified by moduleName.
+ * Removes a setting (property) in a module settings file.
*
- * @param moduleName
- *
- * @return Properties file as specified by moduleName.
- *
- * @throws IOException
+ * @param moduleName The module name.
+ * @param settingName The setting name.
*/
- private static Properties fetchProperties(String moduleName) throws IOException {
- InputStream inputStream = new FileInputStream(getPropertyPath(moduleName));
- Properties props = new Properties();
- props.load(inputStream);
- inputStream.close();
+ public static synchronized void removeProperty(String moduleName, String settingName) {
+ try {
+ if (getConfigSetting(moduleName, settingName) != null) {
+ Properties props = fetchProperties(moduleName);
+ props.remove(settingName);
+ File path = new File(getSettingsFilePath(moduleName));
+ try (FileOutputStream fos = new FileOutputStream(path)) {
+ props.store(fos, "Removed " + settingName); //NON-NLS
+ }
+ }
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, String.format("Error removing %s setting from module settings file at %s)", settingName, getSettingsFilePath(moduleName)), ex); //NON-NLS
+ }
+ }
+
+ /**
+ * Gets the contents of a module settings file as a Properties object.
+ *
+ * @param moduleName The module name.
+ *
+ * @return The Properties object.
+ *
+ * @throws IOException If there is a problem reading the settings file.
+ */
+ private static synchronized Properties fetchProperties(String moduleName) throws IOException {
+ Properties props;
+ try (InputStream inputStream = new FileInputStream(getSettingsFilePath(moduleName))) {
+ props = new Properties();
+ props.load(inputStream);
+ }
return props;
}
/**
- * Gets the property file as specified.
+ * Gets a File object for a module settings (properties) file.
*
- * @param moduleName
+ * @param moduleName The module name.
*
- * @return A new file handle, returns null if the file does not exist.
+ * @return The File object or null if the file does not exist.
*/
- public static File getPropertyFile(String moduleName) {
- String path = getPropertyPath(moduleName);
- if (path == null) {
- return null;
- } else {
- return new File(getPropertyPath(moduleName));
+ public static synchronized File getPropertyFile(String moduleName) {
+ File configFile = null;
+ if (configExists(moduleName)) {
+ configFile = new File(getSettingsFilePath(moduleName));
}
+ return configFile;
}
+
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
+ private ModuleSettings() {
+ }
+
}
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java
index d3a27a1eb3..123ec7d7c3 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java
@@ -286,8 +286,14 @@ public abstract class BaseChildFactory extends ChildFactory.D
* If pageSize is set split keys into pages, otherwise create a
* single page containing all keys.
*/
- if (keys.isEmpty()) {
- pages.clear();
+ if (keys.isEmpty() && !pages.isEmpty()) {
+ /**
+ * If we previously had keys (i.e. pages is not empty) and now
+ * we don't have keys, reset pages to an empty list.
+ * Cannot use a call to List.clear() here because the call to
+ * Lists.partition() below returns an unmodifiable list.
+ */
+ pages = new ArrayList<>();
} else {
pages = Lists.partition(keys, pageSize > 0 ? pageSize : keys.size());
}
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
index b063a0f006..5a02ba9a55 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
@@ -312,7 +312,11 @@ public class BlackboardArtifactNode extends AbstractContentNode sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.geolocation;
import java.awt.BorderLayout;
+import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
@@ -30,6 +31,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
@@ -49,6 +51,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.geolocation.GeoFilterPanel.GeoFilter;
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
+import org.sleuthkit.autopsy.geolocation.datamodel.Track;
import org.sleuthkit.autopsy.geolocation.datamodel.Waypoint;
import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder;
import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder.WaypointFilterQueryCallBack;
@@ -85,12 +88,12 @@ public final class GeolocationTopComponent extends TopComponent {
// This is the hardcoded report name from KMLReport.java
private static final String REPORT_KML = "ReportKML.kml";
-
+
private boolean mapInitalized = false;
@Messages({
"GLTopComponent_name=Geolocation",
- "GLTopComponent_initilzation_error=An error occurred during waypoint initilization. Geolocation data maybe incomplete."
+ "GLTopComponent_initilzation_error=An error occurred during waypoint initilization. Geolocation data maybe incomplete."
})
/**
@@ -113,13 +116,14 @@ public final class GeolocationTopComponent extends TopComponent {
|| eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID()
|| eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID()
|| eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()
- || eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID())) {
+ || eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID()
+ || eventData.getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACK.getTypeID())) {
showRefreshPanel(true);
}
}
};
-
+
this.caseEventListener = pce -> {
mapPanel.clearWaypoints();
if (pce.getNewValue() != null) {
@@ -148,7 +152,7 @@ public final class GeolocationTopComponent extends TopComponent {
filterPane.setPanel(geoFilterPanel);
geoFilterPanel.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(ActionEvent e) {
updateWaypoints();
}
});
@@ -186,7 +190,7 @@ public final class GeolocationTopComponent extends TopComponent {
public void componentOpened() {
super.componentOpened();
WindowManager.getDefault().setTopComponentFloating(this, true);
-
+
}
@Messages({
@@ -199,7 +203,7 @@ public final class GeolocationTopComponent extends TopComponent {
mapPanel.clearWaypoints();
geoFilterPanel.clearDataSourceList();
geoFilterPanel.updateDataSourceList();
-
+
// Let's make sure we only do this on the first open
if (!mapInitalized) {
try {
@@ -217,7 +221,7 @@ public final class GeolocationTopComponent extends TopComponent {
return; // Doen't set the waypoints.
}
}
- mapPanel.setWaypoints(new ArrayList<>());
+ mapPanel.setWaypoints(new LinkedHashSet<>());
updateWaypoints();
}
@@ -227,12 +231,27 @@ public final class GeolocationTopComponent extends TopComponent {
* @param show Whether to show or hide the panel.
*/
private void showRefreshPanel(boolean show) {
- if (show) {
- mapPanel.add(refreshPanel, BorderLayout.NORTH);
- } else {
- mapPanel.remove(refreshPanel);
- }
- mapPanel.revalidate();
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ boolean isShowing = false;
+ Component[] comps = mapPanel.getComponents();
+ for(Component comp: comps) {
+ if(comp.equals(refreshPanel)) {
+ isShowing = true;
+ break;
+ }
+ }
+ if (show && !isShowing) {
+ mapPanel.add(refreshPanel, BorderLayout.NORTH);
+ mapPanel.revalidate();
+ } else if(!show && isShowing){
+ mapPanel.remove(refreshPanel);
+ mapPanel.revalidate();
+ }
+ }
+ });
+
}
/**
@@ -242,7 +261,7 @@ public final class GeolocationTopComponent extends TopComponent {
@Messages({
"GeoTopComponent_no_waypoints_returned_mgs=Applied filter failed to find waypoints that matched criteria.\nRevise filter options and try again.",
"GeoTopComponent_no_waypoints_returned_Title=No Waypoints Found",
- "GeoTopComponent_filter_exception_msg=Exception occured during waypoint filtering.",
+ "GeoTopComponent_filter_exception_msg=Exception occurred during waypoint filtering.",
"GeoTopComponent_filter_exception_Title=Filter Failure",
"GeoTopComponent_filer_data_invalid_msg=Unable to run waypoint filter.\nPlease select one or more data sources.",
"GeoTopComponent_filer_data_invalid_Title=Filter Failure"
@@ -378,7 +397,7 @@ public final class GeolocationTopComponent extends TopComponent {
String reportBaseDir = createReportDirectory();
progressPanel.setLabels(REPORT_KML, reportBaseDir);
-
+
SwingWorker worker = new SwingWorker() {
@Override
protected Void doInBackground() throws Exception {
@@ -406,7 +425,7 @@ public final class GeolocationTopComponent extends TopComponent {
/**
* A runnable class for getting waypoints based on the current filters.
*/
- private class WaypointRunner implements Runnable {
+ private class WaypointRunner implements Runnable, WaypointFilterQueryCallBack {
private final GeoFilter filters;
@@ -428,7 +447,7 @@ public final class GeolocationTopComponent extends TopComponent {
filters.showAllWaypoints(),
filters.getMostRecentNumDays(),
filters.showWaypointsWithoutTimeStamp(),
- new WaypointCallBack());
+ this);
} catch (GeoLocationDataException ex) {
logger.log(Level.SEVERE, "Failed to filter waypoints.", ex);
@@ -439,30 +458,32 @@ public final class GeolocationTopComponent extends TopComponent {
Bundle.GeoTopComponent_filter_exception_Title(),
Bundle.GeoTopComponent_filter_exception_msg(),
JOptionPane.ERROR_MESSAGE);
-
+
setWaypointLoading(false);
}
});
}
}
- }
-
- /**
- * Callback for getting waypoints.
- */
- private class WaypointCallBack implements WaypointFilterQueryCallBack {
-
@Override
- public void process(final List waypoints) {
- // Make sure that the waypoints are added to the map panel in
- // the correct thread.
+ public void process(List waypoints) {
+
+ List