globalTaskList = new ArrayList();
+
+ public static OfflineTaskManager getManager() {
+ if (singleInstance == null) {
+ singleInstance = new OfflineTaskManager();
+ }
+ return singleInstance;
+ }
+
/**
* Get a list of ALL offline tasks registered with all modules
* in all of PAMGUard.
* N.B. Many tasks won't be registered.
* @return list of all offline tasks
*/
- public static ArrayList getAllOfflineTasks() {
- ArrayList allTasks = new ArrayList<>();
- PamController pamController = PamController.getInstance();
- int n = pamController.getNumControlledUnits();
- for (int i = 0; i < n; i++) {
- PamControlledUnit pcu = pamController.getControlledUnit(i);
- ArrayList unitTasks = pcu.getOfflineTasks();
- if (unitTasks != null) {
- allTasks.addAll(unitTasks);
- }
- }
- return allTasks;
+ public ArrayList getAllOfflineTasks() {
+// ArrayList allTasks = new ArrayList<>();
+// PamController pamController = PamController.getInstance();
+// int n = pamController.getNumControlledUnits();
+// for (int i = 0; i < n; i++) {
+// PamControlledUnit pcu = pamController.getControlledUnit(i);
+// ArrayList unitTasks = pcu.getOfflineTasks();
+// if (unitTasks != null) {
+// allTasks.addAll(unitTasks);
+// }
+// }
+// return allTasks;
+ return globalTaskList;
}
/**
@@ -38,7 +50,7 @@ public class OfflineTaskManager {
* @param taskParentDataBlock parent data block for tasks
* @return list of available tasks.
*/
- public static ArrayList getOfflineTasks(PamDataBlock taskParentDataBlock) {
+ public ArrayList getOfflineTasks(PamDataBlock taskParentDataBlock) {
ArrayList allTasks = getAllOfflineTasks();
ArrayList wantedTasks = new ArrayList<>();
for (OfflineTask task : allTasks) {
@@ -50,16 +62,85 @@ public class OfflineTaskManager {
return wantedTasks;
}
+ /**
+ * Get a list of all tasks in the system which associate with the given PAMGuard module
+ * @param pamControlledUnit parent PAMGuard module
+ * @return list of available tasks.
+ */
+ public ArrayList getOfflineTasks(PamControlledUnit pamControlledUnit) {
+ ArrayList allTasks = getAllOfflineTasks();
+ ArrayList wantedTasks = new ArrayList<>();
+ for (OfflineTask task : allTasks) {
+ if (task == null) continue;
+ if (task.getTaskControlledUnit() == pamControlledUnit) {
+ wantedTasks.add(task);
+ }
+ }
+ return wantedTasks;
+ }
+
/**
* Add all available tasks from the system which use the given datablock
- * as input. Note that tasks already in the goup will NOT be added a second time.
+ * as primary input.
* @param taskGroup Task group to add tasks to
* @param taskParentDataBlock parent data block
* @return number of tasks added
*/
- public static int addAvailableTasks(OfflineTaskGroup taskGroup, PamDataBlock taskParentDataBlock) {
+ public int addAvailableTasks(OfflineTaskGroup taskGroup, PamDataBlock taskParentDataBlock) {
ArrayList tasks = getOfflineTasks(taskParentDataBlock);
return taskGroup.addTasks(tasks);
}
+ /**
+ * Register a task in the global list. It's possible some tasks might get
+ * recreated, in which case when registered they will replace the previous one
+ * This will cause trouble if two separate tasks have the same name, but that should
+ * not be possible.
+ * @param offlineTask
+ */
+ public void registerTask(OfflineTask offlineTask) {
+ // if it exists, replace it.
+ OfflineTask existingTask = findOfflineTask(offlineTask);
+ if (existingTask != null) {
+ int ind = globalTaskList.indexOf(existingTask);
+ globalTaskList.set(ind, offlineTask);
+ }
+ else {
+ globalTaskList.add(offlineTask);
+ }
+ }
+
+ /**
+ * find a task with the same module type, module name and task name. This should
+ * be enough to uniquely identify every task.
+ * @param offlineTask
+ * @return matching task or null.
+ */
+ public OfflineTask findOfflineTask(OfflineTask offlineTask) {
+ return findOfflineTask(offlineTask.getUnitType(), offlineTask.getUnitName(), offlineTask.getName());
+ }
+
+ /**
+ * Find a registered task based on it's module type, module name and task name. This should
+ * be enough to uniquely identify every task.
+ * @param unitType
+ * @param unitName
+ * @param taskName
+ * @return matching task or null.
+ */
+ public OfflineTask findOfflineTask(String unitType, String unitName, String taskName) {
+ // could possibly also do a check on class type ????
+ for (OfflineTask aTask : globalTaskList) {
+ if (aTask.getUnitType().equals(unitType) == false) {
+ continue;
+ }
+ if (aTask.getUnitName().equals(unitName) == false) {
+ continue;
+ }
+ if (aTask.getName().equals(taskName)) {
+ return aTask;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/offlineProcessing/TaskActivity.java b/src/offlineProcessing/TaskActivity.java
new file mode 100644
index 00000000..63bfde5b
--- /dev/null
+++ b/src/offlineProcessing/TaskActivity.java
@@ -0,0 +1,7 @@
+package offlineProcessing;
+
+public enum TaskActivity {
+
+ IDLE, PROCESSING, LOADING, LINKING, SAVING;
+
+}
diff --git a/src/offlineProcessing/TaskGroupParams.java b/src/offlineProcessing/TaskGroupParams.java
index c1d7dd46..25497c24 100644
--- a/src/offlineProcessing/TaskGroupParams.java
+++ b/src/offlineProcessing/TaskGroupParams.java
@@ -33,7 +33,7 @@ public class TaskGroupParams implements Cloneable, Serializable, ManagedParamete
static public final int PROCESS_NEW = 2;
/**
- * Time of the last bit of data to be processed.
+ * Time of the last section of data to be processed.
*/
public long lastDataTime;
@@ -91,6 +91,11 @@ public class TaskGroupParams implements Cloneable, Serializable, ManagedParamete
*/
public ArrayList timeChunks;
+ /**
+ * Note which will get written to the database of completed tasks.
+ */
+ public String taskNote;
+
/**
* Set the selection state of a particular task.
* @param iTask task number (counting from 0)
diff --git a/src/offlineProcessing/TaskLogging.java b/src/offlineProcessing/TaskLogging.java
deleted file mode 100644
index 1fc3c1ce..00000000
--- a/src/offlineProcessing/TaskLogging.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package offlineProcessing;
-
-import java.sql.Connection;
-import java.sql.Types;
-
-import PamController.PamControlledUnit;
-import PamUtils.PamCalendar;
-import generalDatabase.DBControlUnit;
-import generalDatabase.EmptyTableDefinition;
-import generalDatabase.PamConnection;
-import generalDatabase.PamTableItem;
-import generalDatabase.SQLTypes;
-
-/**
- * Handles logging of tasks to the database.
- *
- * @author Doug Gillespie
- *
- */
-public class TaskLogging {
-
- private static TaskLogging taskLogging;
- private EmptyTableDefinition tableDef;
- private PamTableItem localTime, moduleType, moduleName, taskName, taskStart, taskStartMillis, taskEnd, taskEndMillis,
- completionCode;
-
- private PamConnection con;
-
- private TaskLogging() {
- tableDef = new EmptyTableDefinition("OfflineTasks");
- tableDef.addTableItem(localTime = new PamTableItem("PCLocalTime", Types.TIMESTAMP));
- tableDef.addTableItem(moduleType = new PamTableItem("Module Type", Types.CHAR, 50));
- tableDef.addTableItem(moduleName = new PamTableItem("Module Name", Types.CHAR, 50));
- tableDef.addTableItem(taskName = new PamTableItem("Task Name", Types.CHAR, 50));
- tableDef.addTableItem(taskStart = new PamTableItem("TaskStart", Types.TIMESTAMP));
- tableDef.addTableItem(taskStartMillis = new PamTableItem("TaskStartMillis", Types.INTEGER));
- tableDef.addTableItem(taskEnd = new PamTableItem("TaskEnd", Types.TIMESTAMP));
- tableDef.addTableItem(taskEndMillis = new PamTableItem("TaskEndMillis", Types.INTEGER));
- tableDef.addTableItem(completionCode = new PamTableItem("CompletionCode", Types.CHAR, 20));
-
- /**
- * Note that completionCode Strings can be got from
- * TaskMonitorData.getStatusString
- */
- }
-
- public static TaskLogging getTaskLogging() {
- if (taskLogging == null) {
- taskLogging = new TaskLogging();
- }
- taskLogging.checkConnection();
- return taskLogging;
- }
-
- private void checkConnection() {
- // TODO Auto-generated method stub
- PamConnection currentCon = DBControlUnit.findConnection();
- if (currentCon == con) {
- return;
- }
- /**
- * Need to check tables, etc.
- */
- currentCon = con;
- DBControlUnit.findDatabaseControl().getDbProcess().checkTable(tableDef);
- }
-
- public boolean logTask(PamControlledUnit pcu, SQLTypes sqlTypes, OfflineTask task, long startTime,
- long endTime, int completionStatus) {
- localTime.setValue(sqlTypes.getTimeStamp(System.currentTimeMillis()));
- moduleType.setValue(pcu.getUnitType());
- moduleName.setValue(pcu.getUnitType());
- taskName.setValue(task.getName());
- taskStart.setValue(sqlTypes.getTimeStamp(startTime));
- taskEnd.setValue(sqlTypes.getTimeStamp(endTime));
- taskStartMillis.setValue(startTime%1000);
- taskEndMillis.setValue(endTime%1000);
- completionCode.setValue(TaskMonitorData.getStatusString(completionStatus));
-
- return false;
-
- }
-
-}
diff --git a/src/offlineProcessing/TaskMonitor.java b/src/offlineProcessing/TaskMonitor.java
index 623d0802..d2bf2200 100644
--- a/src/offlineProcessing/TaskMonitor.java
+++ b/src/offlineProcessing/TaskMonitor.java
@@ -9,36 +9,43 @@ package offlineProcessing;
*
*/
public interface TaskMonitor {
-
- static public final int TASK_IDLE = 0;
- static public final int TASK_RUNNING = 1;
- static public final int TASK_INTERRRUPTED = 2;
- static public final int TASK_COMPLETE = 3;
- static public final int TASK_CRASHED = 4;
+//
+// static public final int TASK_IDLE = 0;
+// static public final int TASK_STARTING = 1; // before it started.
+// static public final int TASK_RUNNING = 2;
+// static public final int TASK_INTERRRUPTED = 3;
+// static public final int TASK_COMPLETE = 4;
+// static public final int TASK_CRASHED = 5;
- /**
- * Set the task status.
- * @param taskStatus
- */
- public void setStatus(int taskStatus);
+// public static final int ACTIVITY_PROCESSING = 10;
+// public static final int ACTIVITY_LOADING = 11;
+// public static final int ACTIVITY_LINKING = 12;
+// public static final int ACTIVITY_SAVING = 13;
- /**
- * Set the total number of files to process
- * (will be one if only loaded data are being processed).
- * @param nFiles
- */
- public void setNumFiles(int nFiles);
- /**
- * Set the overall task progress
- *
- * @param global - global progress, i.e. number of files completed (0 - nFiles)
- * @param loaded - progress though data currently loaded (0 - 1.)
- */
- public void setProgress(int global, double loaded);
-
- /**
- * Set the current file name.
- * @param fileName
- */
- public void setFileName(String fileName);
+ public void setTaskStatus(TaskMonitorData taskMonitorData);
+// /**
+// * Set the task status.
+// * @param taskStatus
+// */
+// public void setStatus(int taskStatus);
+//
+// /**
+// * Set the total number of files to process
+// * (will be one if only loaded data are being processed).
+// * @param nFiles
+// */
+// public void setNumFiles(int nFiles);
+// /**
+// * Set the overall task progress
+// *
+// * @param global - global progress, i.e. number of files completed (0 - nFiles)
+// * @param loaded - progress though data currently loaded (0 - 1.)
+// */
+// public void setProgress(int global, double loaded);
+//
+// /**
+// * Set the current file name.
+// * @param fileName
+// */
+// public void setFileName(String fileName);
}
diff --git a/src/offlineProcessing/TaskMonitorData.java b/src/offlineProcessing/TaskMonitorData.java
index e32acc24..d290917e 100644
--- a/src/offlineProcessing/TaskMonitorData.java
+++ b/src/offlineProcessing/TaskMonitorData.java
@@ -8,105 +8,128 @@ package offlineProcessing;
*/
public class TaskMonitorData {
- static public final int SET_NFILES = 0x1;
- static public final int SET_FILENAME = 0x2;
- static public final int SET_STATUS = 0x4;
- static public final int SET_PROGRESS = 0x8;
- static public final int LOADING_DATA = 0x10;
- static public final int LINKING_DATA = 0x20;
+// static public final int SET_NFILES = 0x1;
+// static public final int SET_FILENAME = 0x2;
+// static public final int SET_STATUS = 0x4;
+// static public final int SET_PROGRESS = 0x8;
+// static public final int LOADING_DATA = 0x10;
+// static public final int LINKING_DATA = 0x20;
- int dataType;
+ public int progMaximum; // used for both files and units.
- int globalProgress;
+ public int progValue;
- int nFiles;
+ public String fileOrStatus; // will be a file name or the words "Current data" or null
- /**
- * Progress through loaded data
- * Values < 0 represent unknown (i.e. currently loading data).
- * so progress bars should be set to indeterminate.
- */
- double loadedProgress;
+ public TaskStatus taskStatus;
- int status;
+ public TaskActivity taskActivity;
+
+ public long lastDataDate;
- String fileName;
- /**
- * Constructor used to set the status
- * @param status status
- */
- TaskMonitorData(int status) {
- this.status = status;
- dataType = SET_STATUS;
- }
-
- /**
- * Constructor used to set both the status and
- * the total number of files.
- * @param status status
- * @param nFiles number of files
- */
- TaskMonitorData(int status, int nFiles) {
- this.status = status;
- this.nFiles = nFiles;
- dataType = SET_STATUS | SET_NFILES;
- }
-
- /**
- * Constructor used to set the current file name
- * @param fileName file Name
- */
- TaskMonitorData(String fileName) {
- this.fileName = fileName;
- dataType = SET_FILENAME;
- }
-
- /**
- * Constructor used to set the analysis progress.
- * @param globalProgress
- * @param loadedProgress
- */
- TaskMonitorData(int globalProgress, double loadedProgress) {
- this.globalProgress = globalProgress;
- this.loadedProgress = loadedProgress;
- dataType = SET_PROGRESS;
+ public TaskMonitorData(TaskStatus taskStatus, TaskActivity taskActivity, int totalFiles, int currentFile,
+ String fileOrStatus, long lastDataDate) {
+ super();
+ this.progMaximum = totalFiles;
+ this.progValue = currentFile;
+ this.fileOrStatus = fileOrStatus;
+ this.taskStatus = taskStatus;
+ this.taskActivity = taskActivity;
+ this.lastDataDate = lastDataDate;
}
+
+// int dataType;
+//
+// int globalProgress;
+//
+// int nFiles;
+//
+// /**
+// * Progress through loaded data
+// * Values < 0 represent unknown (i.e. currently loading data).
+// * so progress bars should be set to indeterminate.
+// */
+// double loadedProgress;
+//
+// int status;
+//
+// String fileName;
+//
+//
+// /**
+// * Constructor used to set the status
+// * @param status status
+// */
+// TaskMonitorData(int status) {
+// this.status = status;
+// dataType = SET_STATUS;
+// }
+//
+// /**
+// * Constructor used to set both the status and
+// * the total number of files.
+// * @param status status
+// * @param nFiles number of files
+// */
+// TaskMonitorData(int status, int nFiles) {
+// this.status = status;
+// this.nFiles = nFiles;
+// dataType = SET_STATUS | SET_NFILES;
+// }
+//
+// /**
+// * Constructor used to set the current file name
+// * @param fileName file Name
+// */
+// TaskMonitorData(String fileName) {
+// this.fileName = fileName;
+// dataType = SET_FILENAME;
+// }
+//
+// /**
+// * Constructor used to set the analysis progress.
+// * @param globalProgress
+// * @param loadedProgress
+// */
+// TaskMonitorData(int globalProgress, double loadedProgress) {
+// this.globalProgress = globalProgress;
+// this.loadedProgress = loadedProgress;
+// dataType = SET_PROGRESS;
+// }
- /**
- *
- * @param status Task status
- * @return some string or other to represent the status.
- */
- public static String getStatusString(int status) {
- switch(status) {
- case TaskMonitor.TASK_IDLE:
- return "Idle";
- case TaskMonitor.TASK_COMPLETE:
- return "Done";
- case TaskMonitor.TASK_INTERRRUPTED:
- return "Interrupted";
- case TaskMonitor.TASK_RUNNING:
- return "Running";
- case TaskMonitor.TASK_CRASHED:
- return "Crashed";
- }
- return "Unknown";
- }
+// /**
+// *
+// * @param status Task status
+// * @return some string or other to represent the status.
+// */
+// public static String getStatusString(int status) {
+// switch(status) {
+// case TaskMonitor.TASK_COMPLETE:
+// return "Done";
+// case TaskMonitor.TASK_INTERRRUPTED:
+// return "Interrupted";
+// case TaskMonitor.TASK_RUNNING:
+// return "Running";
+// case TaskMonitor.TASK_CRASHED:
+// return "Crashed";
+// }
+// return "Unknown";
+// }
- /**
- * Turn a status string back into a code.
- * @param statusString
- * @return
- */
- public static int getStatusCode(String statusString) {
- for (int i = 0; i < 5; i++) {
- if (statusString.equals(getStatusString(i))) {
- return i;
- }
- }
- return -1;
- }
+// /**
+// * Turn a status string back into a code.
+// * @param statusString
+// * @return
+// */
+// public static int getStatusCode(String statusString) {
+// for (int i = 0; i < 5; i++) {
+// if (statusString.equals(getStatusString(i))) {
+// return i;
+// }
+// }
+// return -1;
+// }
}
diff --git a/src/offlineProcessing/TaskStatus.java b/src/offlineProcessing/TaskStatus.java
new file mode 100644
index 00000000..556a3b2e
--- /dev/null
+++ b/src/offlineProcessing/TaskStatus.java
@@ -0,0 +1,19 @@
+package offlineProcessing;
+
+public enum TaskStatus {
+ //
+// static public final int TASK_IDLE = 0;
+// static public final int TASK_STARTING = 1; // before it started.
+// static public final int TASK_RUNNING = 2;
+// static public final int TASK_INTERRRUPTED = 3;
+// static public final int TASK_COMPLETE = 4;
+// static public final int TASK_CRASHED = 5;
+ IDLE, STARTING, RUNNING, INTERRUPTED, COMPLETE, CRASHED;
+
+ @Override
+ public String toString() {
+ return super.toString();
+ }
+
+
+}
diff --git a/src/offlineProcessing/TaskStatusData.java b/src/offlineProcessing/TaskStatusData.java
new file mode 100644
index 00000000..7770ad20
--- /dev/null
+++ b/src/offlineProcessing/TaskStatusData.java
@@ -0,0 +1,9 @@
+package offlineProcessing;
+
+public class TaskStatusData {
+
+ public TaskStatusData() {
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/src/offlineProcessing/OfflineProcessingControlledUnit.java b/src/offlineProcessing/legacyremotestuff/OfflineProcessingControlledUnit.java
similarity index 94%
rename from src/offlineProcessing/OfflineProcessingControlledUnit.java
rename to src/offlineProcessing/legacyremotestuff/OfflineProcessingControlledUnit.java
index 888409a2..ce41e19b 100644
--- a/src/offlineProcessing/OfflineProcessingControlledUnit.java
+++ b/src/offlineProcessing/legacyremotestuff/OfflineProcessingControlledUnit.java
@@ -1,12 +1,12 @@
/**
*
*/
-package offlineProcessing;
+package offlineProcessing.legacyremotestuff;
import java.util.ArrayList;
import dataMap.DataMapPanel;
-
+import offlineProcessing.OfflineTaskGroup;
import PamController.PamControlledUnit;
import PamController.PamController;
import PamController.PamControllerInterface;
@@ -16,6 +16,7 @@ import PamController.PamSettingManager;
* @author GrahamWeatherup
*only run in Viewer mode to run all Offline Tasks
*/
+@Deprecated // too simplistic, won't be using this.
public class OfflineProcessingControlledUnit extends PamControlledUnit{
// static OfflineProcessingControlledUnit singleInstance;
diff --git a/src/offlineProcessing/OfflineProcessingProcess.java b/src/offlineProcessing/legacyremotestuff/OfflineProcessingProcess.java
similarity index 91%
rename from src/offlineProcessing/OfflineProcessingProcess.java
rename to src/offlineProcessing/legacyremotestuff/OfflineProcessingProcess.java
index a15156f5..3e12bf16 100644
--- a/src/offlineProcessing/OfflineProcessingProcess.java
+++ b/src/offlineProcessing/legacyremotestuff/OfflineProcessingProcess.java
@@ -1,11 +1,12 @@
/**
*
*/
-package offlineProcessing;
+package offlineProcessing.legacyremotestuff;
import PamController.PamControlledUnit;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
+import offlineProcessing.OfflineTask;
/**
* @author GrahamWeatherup
diff --git a/src/offlineProcessing/OfflineTaskRegister.java b/src/offlineProcessing/legacyremotestuff/OfflineTaskRegister.java
similarity index 73%
rename from src/offlineProcessing/OfflineTaskRegister.java
rename to src/offlineProcessing/legacyremotestuff/OfflineTaskRegister.java
index 5a13cd6e..74b5a504 100644
--- a/src/offlineProcessing/OfflineTaskRegister.java
+++ b/src/offlineProcessing/legacyremotestuff/OfflineTaskRegister.java
@@ -1,4 +1,4 @@
-package offlineProcessing;
+package offlineProcessing.legacyremotestuff;
/**
@@ -8,6 +8,7 @@ package offlineProcessing;
* @author Jamie Macaulay
*
*/
+@Deprecated // there is nothing in here which shouldn't be in OfflineTaskManager
public class OfflineTaskRegister {
/**
diff --git a/src/offlineProcessing/offlineProcessingPlugin.java b/src/offlineProcessing/legacyremotestuff/offlineProcessingPlugin.java
similarity index 98%
rename from src/offlineProcessing/offlineProcessingPlugin.java
rename to src/offlineProcessing/legacyremotestuff/offlineProcessingPlugin.java
index 8b77c0d4..033d804b 100644
--- a/src/offlineProcessing/offlineProcessingPlugin.java
+++ b/src/offlineProcessing/legacyremotestuff/offlineProcessingPlugin.java
@@ -22,7 +22,7 @@
-package offlineProcessing;
+package offlineProcessing.legacyremotestuff;
import PamModel.PamDependency;
import PamModel.PamPluginInterface;
diff --git a/src/offlineProcessing/logging/OldTaskData.java b/src/offlineProcessing/logging/OldTaskData.java
new file mode 100644
index 00000000..ec30c09c
--- /dev/null
+++ b/src/offlineProcessing/logging/OldTaskData.java
@@ -0,0 +1,53 @@
+package offlineProcessing.logging;
+
+import PamUtils.PamCalendar;
+import offlineProcessing.TaskActivity;
+import offlineProcessing.TaskMonitorData;
+import offlineProcessing.TaskStatus;
+
+public class OldTaskData extends TaskMonitorData {
+
+ public long firstDataDate;
+
+ public long processingStart, processingEnd;
+
+ private String taskNote;
+
+ /**
+ *
+ * @param taskStatus completion status of task
+ * @param firstDataDate first data date
+ * @param lastDataDate last data date
+ * @param procStart date run started
+ * @param procEnd date run ended.
+ * @param taskNote
+ */
+ public OldTaskData(TaskStatus taskStatus, long firstDataDate,
+ long lastDataDate, long procStart, long procEnd, String taskNote) {
+ super(taskStatus, TaskActivity.IDLE, 0, 0, null, lastDataDate);
+ this.firstDataDate = firstDataDate;
+ this.processingStart = procStart;
+ this.processingEnd = procEnd;
+ this.taskNote = taskNote;
+ }
+
+ @Override
+ public String toString() {
+ String endStatus;
+ if (this.taskStatus == null) {
+ endStatus = "Unknown completion code. Possible crash";
+ }
+ else {
+ endStatus = this.taskStatus.toString();
+ }
+ String str = String.format("Processed from %s to %s on %s. %s", PamCalendar.formatDateTime(firstDataDate),
+ PamCalendar.formatDateTime(lastDataDate), PamCalendar.formatDateTime(this.processingStart), endStatus);
+ if (taskNote != null) {
+ str = str + "\n" + taskNote;
+// str = "" + str + "\br" + taskNote + "<\\html>";
+ }
+ return str;
+ }
+
+
+}
diff --git a/src/offlineProcessing/logging/TaskLogging.java b/src/offlineProcessing/logging/TaskLogging.java
new file mode 100644
index 00000000..1193e05f
--- /dev/null
+++ b/src/offlineProcessing/logging/TaskLogging.java
@@ -0,0 +1,300 @@
+package offlineProcessing.logging;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.HashMap;
+
+import PamController.PamControlledUnit;
+import PamUtils.PamCalendar;
+import PamguardMVC.PamDataBlock;
+import PamguardMVC.PamDataUnit;
+import generalDatabase.DBControlUnit;
+import generalDatabase.EmptyTableDefinition;
+import generalDatabase.PamConnection;
+import generalDatabase.PamTableItem;
+import generalDatabase.SQLLogging;
+import generalDatabase.SQLTypes;
+import generalDatabase.pamCursor.CursorFinder;
+import generalDatabase.pamCursor.PamCursor;
+import offlineProcessing.OfflineTask;
+import offlineProcessing.OfflineTaskGroup;
+import offlineProcessing.TaskActivity;
+import offlineProcessing.TaskGroupParams;
+import offlineProcessing.TaskMonitorData;
+import offlineProcessing.TaskStatus;
+
+/**
+ * Handles logging of tasks to the database.
+ *
+ * @author Doug Gillespie
+ *
+ */
+public class TaskLogging {
+
+
+ private static TaskLogging taskLogging;
+
+ public static final int TASK_NOTE_LENGTH = 80;
+
+ private EmptyTableDefinition tableDef;
+ private PamTableItem utc, moduleType, moduleName, taskName, dataStart, dataEnd, runEnd,
+ completionCode, note;
+
+ /**
+ * Storage mostly to keep id's of last database index for each task.
+ */
+ private HashMap loggingData = new HashMap();
+
+ /*
+ * May want several different write and update cursors for this. e.g. when a task starts
+ * we want to write the UTC and id comlumns and the dataStart, but probably not the dataEnd and
+ * the runEnd columns. Then when we update (if we update) we'll occasionally update the dataEnd
+ * time, then only will in the runEnd and completionCode when the task has finished.
+ */
+ private EmptyTableDefinition startTableDef, updateTableDef, completeTableDef;
+
+ private PamConnection con;
+
+ private static final String tableName = "OfflineTasks";
+
+// private StartLogging startLogging;
+ private CursorFinder startCursorFinder, completeCursorFinder;
+
+ private TaskLoggingDataBlock taskLoggingDataBlock;
+
+ private TaskLogging() {
+ // table for everything (mostly used for reading)
+ tableDef = new EmptyTableDefinition(tableName);
+ tableDef.addTableItem(utc = new PamTableItem("UTC", Types.TIMESTAMP));
+ tableDef.addTableItem(moduleType = new PamTableItem("Module Type", Types.CHAR, 50));
+ tableDef.addTableItem(moduleName = new PamTableItem("Module Name", Types.CHAR, 50));
+ tableDef.addTableItem(taskName = new PamTableItem("Task Name", Types.CHAR, 50));
+ tableDef.addTableItem(dataStart = new PamTableItem("DataStart", Types.TIMESTAMP));
+ tableDef.addTableItem(dataEnd = new PamTableItem("DataEnd", Types.TIMESTAMP));
+ tableDef.addTableItem(runEnd = new PamTableItem("RunEnd", Types.TIMESTAMP));
+ tableDef.addTableItem(completionCode = new PamTableItem("CompletionCode", Types.CHAR, 20));
+ tableDef.addTableItem(note = new PamTableItem("Notes", Types.CHAR, TASK_NOTE_LENGTH));
+
+ taskLoggingDataBlock = new TaskLoggingDataBlock();
+
+ /**
+ * Note that completionCode Strings can be got from
+ * TaskMonitorData.getStatusString
+ */
+ // table for startup write
+ startTableDef = new EmptyTableDefinition(tableName);
+ startTableDef.addTableItem(utc);
+ startTableDef.addTableItem(moduleType);
+ startTableDef.addTableItem(moduleName);
+ startTableDef.addTableItem(taskName);
+ startTableDef.addTableItem(dataStart);
+ startTableDef.addTableItem(note);
+// startLogging = new StartLogging(taskLoggingDataBlock, startTableDef);
+ startCursorFinder = new CursorFinder();
+
+
+ // table for startup write
+ updateTableDef = new EmptyTableDefinition(tableName);
+ updateTableDef.addTableItem(dataEnd);
+
+ // table for startup write
+ completeTableDef = new EmptyTableDefinition(tableName);
+ completeTableDef.addTableItem(dataEnd);
+ completeTableDef.addTableItem(runEnd);
+ completeTableDef.addTableItem(completionCode);
+ completeCursorFinder = new CursorFinder();
+
+
+ }
+
+ public static TaskLogging getTaskLogging() {
+ if (taskLogging == null) {
+ taskLogging = new TaskLogging();
+ }
+ taskLogging.checkConnection();
+ return taskLogging;
+ }
+
+ private boolean checkConnection() {
+ // TODO Auto-generated method stub
+ PamConnection currentCon = DBControlUnit.findConnection();
+ if (currentCon != con) {
+ /**
+ * Need to check tables, etc.
+ */
+ con = currentCon;
+ DBControlUnit.findDatabaseControl().getDbProcess().checkTable(tableDef);
+ }
+ return currentCon != null;
+ }
+
+ public boolean logTask(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
+ if (!checkConnection()) {
+ return false;
+ }
+ switch (monitorData.taskStatus) {
+// case IDLE:
+ case STARTING:
+ return logStart(taskGroup, task, monitorData);
+ case RUNNING:
+ return logUpdate(taskGroup, task, monitorData);
+ case COMPLETE:
+ case CRASHED:
+ case INTERRUPTED:
+ return logComplete(taskGroup, task, monitorData);
+ default:
+ break;
+
+ }
+
+
+ return true;
+ }
+
+ /**
+ * Move all data from the cursor, even though not all objects may get used by the individual cursors.
+ * @param taskGroup
+ * @param task
+ * @param monitorData
+ */
+ private void fillTableData(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
+ TaskGroupParams groupParams = taskGroup.getTaskGroupParams();
+ SQLTypes sqlTypes = con.getSqlTypes();
+ utc.setValue(sqlTypes.getTimeStamp(System.currentTimeMillis()));
+ moduleType.setValue(task.getUnitType());
+ moduleName.setValue(task.getUnitName());
+ taskName.setValue(task.getName());
+ dataStart.setValue(sqlTypes.getTimeStamp(groupParams.startRedoDataTime));
+ dataEnd.setValue(sqlTypes.getTimeStamp(monitorData.lastDataDate));
+ runEnd.setValue(sqlTypes.getTimeStamp(System.currentTimeMillis()));
+ completionCode.setValue(monitorData.taskStatus.toString());
+ note.setValue(groupParams.taskNote);
+ }
+
+ /**
+ * Get TaskMonitorData from the database cursor.
+ * @param taskGroup
+ * @param task
+ * @return
+ */
+ private OldTaskData readTableData() {
+ SQLTypes sqlTypes = con.getSqlTypes();
+ long utc = SQLTypes.millisFromTimeStamp(this.utc.getValue());
+ String modType = moduleType.getDeblankedStringValue();
+ String modName = moduleName.getDeblankedStringValue();
+ String tskName = taskName.getDeblankedStringValue();
+ long dStart = SQLTypes.millisFromTimeStamp(dataStart.getValue());
+ long dEnd = SQLTypes.millisFromTimeStamp(dataEnd.getValue());
+ long procEnd = SQLTypes.millisFromTimeStamp(runEnd.getValue());
+ String compStatus = completionCode.getDeblankedStringValue();
+ TaskStatus status = null;
+ try {
+ status = TaskStatus.valueOf(TaskStatus.class, compStatus);
+ }
+ catch (IllegalArgumentException e) {
+ System.out.printf("Uknown completion code \"%s\" for task %s ended at %s\n", compStatus, tskName, PamCalendar.formatDateTime(dEnd));
+ }
+ String taskNote = note.getDeblankedStringValue();
+ OldTaskData monData = new OldTaskData(status, dStart, dEnd, utc, procEnd, taskNote);
+ return monData;
+ }
+
+ /**
+ * Get the last data for an offline task.
+ * @param taskGroup
+ * @param task
+ * @return
+ */
+ public OldTaskData readLastTaskData(OfflineTaskGroup taskGroup, OfflineTask task) {
+ if (!checkConnection()) {
+ return null;
+ }
+ OldTaskData taskMonitorData = null;
+ String clause;
+ if (taskGroup == null) {
+ // only query on the task name (not good if there is more than one module with the same tasks)
+ clause = String.format(" WHERE TRIM(%s)='%s' ORDER BY Id DESC", taskName.getName(), task.getName());
+ }
+ else {
+ clause = String.format(" WHERE TRIM(%s)='%s' AND TRIM(%s)='%s' AND TRIM(%s)='%s' ORDER BY Id DESC",
+ moduleType.getName(), task.getUnitType(),
+ moduleName.getName(), task.getUnitName(),
+ taskName.getName(), task.getName());
+ }
+ String selStr = tableDef.getSQLSelectString(con.getSqlTypes()) + clause;
+ try {
+ Statement selStmt = con.getConnection().createStatement();
+ ResultSet results = selStmt.executeQuery(selStr);
+ if (results.next()) {
+ for (int i = 0; i < tableDef.getTableItemCount(); i++) {
+ PamTableItem tableItem = tableDef.getTableItem(i);
+ tableItem.setValue(results.getObject(i+1));
+ }
+ taskMonitorData = readTableData();
+ }
+ selStmt.close();
+ } catch (SQLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return taskMonitorData;
+ }
+
+ private boolean logStart(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
+ fillTableData(taskGroup, task, monitorData);
+ PamCursor startCursor = startCursorFinder.getCursor(con, startTableDef);
+ int dbInd = startCursor.immediateInsert(con);
+ if (dbInd > 0) {
+ loggingData.put(task, new TaskLoggingData(task, dbInd, monitorData));
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ private boolean logUpdate(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ private boolean logComplete(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
+ fillTableData(taskGroup, task, monitorData);
+ PamCursor startCursor = completeCursorFinder.getCursor(con, completeTableDef);
+ TaskLoggingData taskLogData = loggingData.get(task);
+ if (taskLogData == null) {
+ System.out.println("No logging data to update for offline task " + task.getName());
+ return false;
+ }
+ completeTableDef.getIndexItem().setValue(taskLogData.databaseIndex);
+ boolean updateOk = startCursor.immediateUpdate(con);
+ if (updateOk) {
+ taskLogData.monitorData = monitorData;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+// private class StartLogging extends SQLLogging {
+//
+// protected StartLogging(TaskLoggingDataBlock pamDataBlock, EmptyTableDefinition startTableDef) {
+// super(pamDataBlock);
+// setTableDefinition(startTableDef);
+// }
+//
+// @Override
+// public void setTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) {
+// // TODO Auto-generated method stub
+//
+// }
+//
+// }
+
+}
diff --git a/src/offlineProcessing/logging/TaskLoggingData.java b/src/offlineProcessing/logging/TaskLoggingData.java
new file mode 100644
index 00000000..24d22c40
--- /dev/null
+++ b/src/offlineProcessing/logging/TaskLoggingData.java
@@ -0,0 +1,26 @@
+package offlineProcessing.logging;
+
+import PamguardMVC.PamDataUnit;
+import offlineProcessing.OfflineTask;
+import offlineProcessing.TaskMonitorData;
+
+/**
+ * Wee class for holding the latest data on each task, most importantly the
+ * database index which is needed for updates.
+ * @author dg50
+ *
+ */
+public class TaskLoggingData extends PamDataUnit {
+
+ protected OfflineTask task;
+ protected int databaseIndex;
+ protected TaskMonitorData monitorData;
+
+ public TaskLoggingData(OfflineTask task, int databaseIndex, TaskMonitorData monitorData) {
+ super(System.currentTimeMillis());
+ this.task = task;
+ this.databaseIndex = databaseIndex;
+ this.monitorData = monitorData;
+ }
+
+}
diff --git a/src/offlineProcessing/logging/TaskLoggingDataBlock.java b/src/offlineProcessing/logging/TaskLoggingDataBlock.java
new file mode 100644
index 00000000..9740137f
--- /dev/null
+++ b/src/offlineProcessing/logging/TaskLoggingDataBlock.java
@@ -0,0 +1,17 @@
+package offlineProcessing.logging;
+
+import PamguardMVC.PamDataBlock;
+import PamguardMVC.PamProcess;
+
+/**
+ * Dummy datablock to use with some dummy SQLLogging classes in TaskLogging.
+ * @author dg50
+ *
+ */
+public class TaskLoggingDataBlock extends PamDataBlock {
+
+ public TaskLoggingDataBlock() {
+ super(TaskLoggingData.class, "Logging data", null, 0);
+ }
+
+}
diff --git a/src/pamViewFX/PamGuiManagerFX.java b/src/pamViewFX/PamGuiManagerFX.java
index 59768e90..37512661 100644
--- a/src/pamViewFX/PamGuiManagerFX.java
+++ b/src/pamViewFX/PamGuiManagerFX.java
@@ -880,8 +880,9 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
pamController.saveViewerData();
}
- // deal with anything that needs sorting out in the realm of UID's.
- pamController.getUidManager().runShutDownOps();
+// // deal with anything that needs sorting out in the realm of UID's.
+ // move this to pamController.pamClose()
+// pamController.getUidManager().runShutDownOps();
// if the user doesn't want to save the config file, make sure they know
// that they'll lose any changes to the settings
diff --git a/src/pamguard/Pamguard.java b/src/pamguard/Pamguard.java
index 31ccc8a0..f1f7aaa1 100644
--- a/src/pamguard/Pamguard.java
+++ b/src/pamguard/Pamguard.java
@@ -23,6 +23,7 @@ package pamguard;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
+import Acquisition.AcquisitionControl;
import Acquisition.FolderInputSystem;
import PamController.PamController;
import PamController.PamGUIManager;
@@ -229,6 +230,14 @@ public class Pamguard {
// source folder for wav files (or other supported sound files)
GlobalArguments.setParam(FolderInputSystem.GlobalWavFolderArg, args[iArg++]);
}
+ else if (anArg.equalsIgnoreCase(PamController.AUTOSTART)) {
+ // auto start processing.
+ GlobalArguments.setParam(PamController.AUTOSTART, PamController.AUTOSTART);
+ }
+ else if (anArg.equalsIgnoreCase(PamController.AUTOEXIT)) {
+ // auto exit at end of processing.
+ GlobalArguments.setParam(PamController.AUTOEXIT, PamController.AUTOEXIT);
+ }
else if (anArg.equalsIgnoreCase("-help")) {
System.out.println("--PamGuard Help");
System.out.println("\n--For standard GUI deployment run without any options.\n");
@@ -329,10 +338,16 @@ public class Pamguard {
Thread.setDefaultUncaughtExceptionHandler(new PamExceptionHandler());
System.setProperty("sun.awt.exception.handler", PamExceptionHandler.class.getName());
- //Amongst other stuff the call to PamController.create()
- //will build and show the GUI and the user can't
- //do much else until that's done so let's have all
- //that kicked off from with the EDT CJB 2009-06-16
+ /*
+ * Amongst other stuff the call to PamController.create()
+ * will build and show the GUI and the user can't
+ * do much else until that's done so let's have all
+ * that kicked off from with the EDT CJB 2009-06-16
+ * Either of these will call .create, just one is in a different
+ * thread, so it's at the end of the create function that other automatic
+ * processes should be started.
+ *
+ */
if (PamGUIManager.isSwing()) {
SwingUtilities.invokeLater(createPamguard);