Skip to content

Commit

Permalink
Add logic to handle task source history. Starting without any storage…
Browse files Browse the repository at this point in the history
… yet.
  • Loading branch information
hptruong93 committed May 23, 2022
1 parent 254d328 commit 82412ac
Show file tree
Hide file tree
Showing 12 changed files with 236 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/core/userDefinedTask/TaskSourceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public static boolean submitTask(UserDefinedAction task, String source) {
return false;
}

task.setSourcePath(FileUtility.getRelativePwdPath(sourceFile));
String relativePath = FileUtility.getRelativePwdPath(sourceFile);
task.setSourcePath(relativePath);
task.recordSourceHistory(relativePath);
return true;
}

Expand Down
14 changes: 14 additions & 0 deletions src/core/userDefinedTask/UserDefinedAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import core.languageHandler.compiler.AbstractNativeCompiler;
import core.languageHandler.compiler.DynamicCompilerManager;
import core.languageHandler.compiler.RemoteRepeatsCompiler;
import core.userDefinedTask.internals.TaskSourceHistory;
import core.userDefinedTask.internals.TaskSourceHistoryEntry;
import utilities.FileUtility;
import utilities.ILoggable;
import utilities.json.IJsonable;
Expand All @@ -39,7 +41,9 @@ public abstract class UserDefinedAction implements IJsonable, ILoggable {

// This is to enable invoking task programmatically.
protected TaskInvoker taskInvoker;

protected UsageStatistics statistics;
protected TaskSourceHistory sourceHistory;

public UserDefinedAction() {
this(UUID.randomUUID().toString());
Expand All @@ -51,6 +55,7 @@ protected UserDefinedAction(String actionId) {
invoker = TaskActivation.newBuilder().build();
invokingKeyChain = new KeyChain();
statistics = new UsageStatistics();
sourceHistory = new TaskSourceHistory();
enabled = true;
}

Expand Down Expand Up @@ -123,6 +128,10 @@ public final void setSourcePath(String sourcePath) {
this.sourcePath = sourcePath;
}

public final void recordSourceHistory(String sourcePath) {
sourceHistory.addEntry(TaskSourceHistoryEntry.of(sourcePath));
}

public final Language getCompiler() {
return compiler;
}
Expand Down Expand Up @@ -151,10 +160,15 @@ public final UsageStatistics getStatistics() {
return statistics;
}

public final TaskSourceHistory getTaskSourceHistory() {
return sourceHistory;
}

public final void override(UserDefinedAction other) {
setName(other.getName());
activation.copy(other.activation);
statistics = other.statistics;
sourceHistory.addHistory(other.sourceHistory);
}

/**
Expand Down
46 changes: 46 additions & 0 deletions src/core/userDefinedTask/internals/TaskSourceHistory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package core.userDefinedTask.internals;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/** Contains information about the source history of a task. */
public class TaskSourceHistory {

private List<TaskSourceHistoryEntry> entries;

public TaskSourceHistory() {
this.entries = new ArrayList<>();
}

/**
* Finds a particular entry given the timestamp.
*
* @param timestamp the timestamp to find the entry for.
* @return the found entry, or null if no entry was found.
*/
public TaskSourceHistoryEntry findEntry(long timestamp) {
for (TaskSourceHistoryEntry entry : entries) {
if (entry.getCreated().getTimeInMillis() == timestamp) {
return entry;
}
}
return null;
}

// Adds a single entry to the history.
public void addEntry(TaskSourceHistoryEntry entry) {
this.entries.add(entry);
}

/// Adds all history to this history.
public void addHistory(TaskSourceHistory history) {
entries.addAll(history.entries);
entries.sort((e1, e2) -> e2.getCreated().compareTo(e1.getCreated()));
}

// Returns the list of entries sorted in reverse chronological order.
public List<TaskSourceHistoryEntry> getEntries() {
return entries.stream().sorted((e1, e2) -> e2.getCreated().compareTo(e1.getCreated())).collect(Collectors.toList());
}
}
26 changes: 26 additions & 0 deletions src/core/userDefinedTask/internals/TaskSourceHistoryEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package core.userDefinedTask.internals;

import java.util.Calendar;

/** Holds a single entry of source history. */
public class TaskSourceHistoryEntry {
private String sourcePath;
private Calendar created;

private TaskSourceHistoryEntry(String sourcePath, Calendar created) {
this.sourcePath = sourcePath;
this.created = created;
}

public static TaskSourceHistoryEntry of(String path) {
return new TaskSourceHistoryEntry(path, Calendar.getInstance());
}

public String getSourcePath() {
return sourcePath;
}

public Calendar getCreated() {
return created;
}
}
2 changes: 2 additions & 0 deletions src/core/webui/server/UIServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
import core.webui.server.handlers.internals.taskmanagement.GetRenderedTaskGroupsSelectModalHandler;
import core.webui.server.handlers.internals.tasks.ActionSaveTaskActivationHandler;
import core.webui.server.handlers.internals.tasks.GetRunTaskConfigHandler;
import core.webui.server.handlers.internals.tasks.GetTaskSourceHandler;
import core.webui.server.handlers.internals.tasks.ModifyTaskNameHandler;
import core.webui.server.handlers.internals.tasks.RunTaskHandler;
import core.webui.server.handlers.internals.tasks.SaveRunTaskConfigHandler;
Expand Down Expand Up @@ -277,6 +278,7 @@ private Map<String, HttpHandlerWithBackend> createHandlers() {
output.put("/internals/get/mouse-position", new GetMousePositionHandler());
output.put("/internals/get/path-suggestion", new GetPathSuggestionHandler());
output.put("/internals/get/source-templates", new GetSourceTemplateHandler());
output.put("/internals/get/task-source", new GetTaskSourceHandler());
output.put("/internals/get/rendered-task-groups-dropdown", new GetRenderedTaskGroupsDropdown(objectRenderer));
output.put("/internals/get/rendered-task-groups-select-modal", new GetRenderedTaskGroupsSelectModalHandler(objectRenderer));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package core.webui.server.handlers.internals.tasks;

import java.io.IOException;
import java.util.Map;

import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.nio.protocol.HttpAsyncExchange;
import org.apache.http.protocol.HttpContext;

import core.userDefinedTask.UserDefinedAction;
import core.webui.server.handlers.AbstractSingleMethodHttpHandler;
import core.webui.webcommon.HttpServerUtilities;

public class GetTaskSourceHandler extends AbstractSingleMethodHttpHandler {

public GetTaskSourceHandler() {
super(AbstractSingleMethodHttpHandler.GET_METHOD);
}

@Override
protected Void handleAllowedRequestWithBackend(HttpRequest request, HttpAsyncExchange exchange, HttpContext context)
throws HttpException, IOException {
String uriString = request.getRequestLine().getUri();
Map<String, String> params = HttpServerUtilities.parseGetParameters(uriString);
if (params == null) {
return HttpServerUtilities.prepareHttpResponse(exchange, 500, "Failed to parse URL " + uriString);
}

String id = params.get("id");
if (id == null || id.isEmpty()) {
return HttpServerUtilities.prepareHttpResponse(exchange, 400, "Task ID is empty or not provided.");
}

String timestampString = params.get("timestamp");
if (timestampString == null || timestampString.isEmpty()) {
return HttpServerUtilities.prepareHttpResponse(exchange, 400, "Timestamp is empty or not provided.");
}

UserDefinedAction action = backEndHolder.getTask(id);
if (action == null) {
return HttpServerUtilities.prepareHttpResponse(exchange, 404, "No action for ID " + id + ".");
}

Long timestamp = Long.parseLong(timestampString);
String sourceCode = backEndHolder.getSourceForTask(action, timestamp);
if (sourceCode == null) {
return HttpServerUtilities.prepareHttpResponse(exchange, 500, "No source code found for task " + id + ".");
}

return HttpServerUtilities.prepareTextResponse(exchange, 200, sourceCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public class RenderedDetailedUserDefinedAction {
private RenderedTaskActivation activation;
private String hasStatistics;
private RenderedUserDefinedActionStatistics statistics;
private String hasSourceHistory;
private RenderedTaskSourceHistory sourceHistory;

private RenderedDetailedUserDefinedAction() {}

Expand All @@ -21,6 +23,8 @@ public static RenderedDetailedUserDefinedAction withEmptyTaskInfo(TaskActivation
result.activation = RenderedTaskActivation.fromActivation(activationConstructor);
result.hasStatistics = false + "";
result.statistics = null;
result.hasSourceHistory = false + "";
result.sourceHistory = null;
return result;
}

Expand All @@ -32,6 +36,8 @@ public static RenderedDetailedUserDefinedAction fromHotkey(String id, String nam
result.activation = RenderedTaskActivation.fromActivation(activationConstructor);
result.hasStatistics = false + "";
result.statistics = null;
result.hasSourceHistory = false + "";
result.sourceHistory = null;
return result;
}

Expand All @@ -43,6 +49,8 @@ public static RenderedDetailedUserDefinedAction fromUserDefinedAction(UserDefine
result.activation = RenderedTaskActivation.fromActivation(activationConstructor);
result.hasStatistics = true + "";
result.statistics = RenderedUserDefinedActionStatistics.fromUserDefinedActionStatistics(action.getStatistics());
result.hasSourceHistory = true + "";
result.sourceHistory = RenderedTaskSourceHistory.of(action.getActionId(), action.getTaskSourceHistory());
return result;
}

Expand Down Expand Up @@ -76,6 +84,12 @@ public RenderedUserDefinedActionStatistics getStatistics() {
public void setStatistics(RenderedUserDefinedActionStatistics statistics) {
this.statistics = statistics;
}
public String getHasSourceHistory() {
return hasSourceHistory;
}
public RenderedTaskSourceHistory getSourceHistory() {
return sourceHistory;
}
public String getIsEnabled() {
return isEnabled;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package core.webui.server.handlers.renderedobjects;

import java.util.List;
import java.util.stream.Collectors;

import core.userDefinedTask.internals.TaskSourceHistory;

public class RenderedTaskSourceHistory {

private List<RenderedTaskSourceHistoryEntry> entries;

public static RenderedTaskSourceHistory of(String taskId, TaskSourceHistory history) {
RenderedTaskSourceHistory result = new RenderedTaskSourceHistory();
result.entries = history.getEntries().stream().map(e -> RenderedTaskSourceHistoryEntry.of(taskId, e)).collect(Collectors.toList());
return result;
}

public List<RenderedTaskSourceHistoryEntry> getEntries() {
return entries;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package core.webui.server.handlers.renderedobjects;

import core.userDefinedTask.internals.TaskSourceHistoryEntry;
import utilities.DateUtility;

public class RenderedTaskSourceHistoryEntry {
private String taskId;
private String createdTime;
private String createdTimeMillis;

public static RenderedTaskSourceHistoryEntry of(String taskId, TaskSourceHistoryEntry entry) {
RenderedTaskSourceHistoryEntry result = new RenderedTaskSourceHistoryEntry();
result.taskId = taskId;
result.createdTime = DateUtility.calendarToTimeString(entry.getCreated());
result.createdTimeMillis = entry.getCreated().getTimeInMillis() + "";
return result;
}

public String getTaskId() {
return taskId;
}
public String getCreatedTime() {
return createdTime;
}
public String getCreatedTimeMillis() {
return createdTimeMillis;
}
}
11 changes: 11 additions & 0 deletions src/frontEnd/MainBackEndHolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import core.userDefinedTask.internals.RemoteRepeatsClientTools;
import core.userDefinedTask.internals.RunActionConfig;
import core.userDefinedTask.internals.SharedVariablesPubSubManager;
import core.userDefinedTask.internals.TaskSourceHistoryEntry;
import globalListener.GlobalListenerHookController;
import staticResources.BootStrapResources;
import utilities.Desktop;
Expand Down Expand Up @@ -857,6 +858,16 @@ public void switchEnableTask(UserDefinedAction action) {
}
}

public String getSourceForTask(UserDefinedAction action, long timestamp) {
TaskSourceHistoryEntry entry = action.getTaskSourceHistory().findEntry(timestamp);
if (entry == null) {
LOGGER.warning("No source path for action " + action.getName() + " at time " + timestamp + ".");
return null;
}

return FileUtility.readFromFile(entry.getSourcePath()).toString();
}

/**
* Populate all tasks with task invoker to dynamically execute other tasks.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<#macro fragment>
<#if task.hasSourceHistory == "true">
<h1> Source history </h1>
<table>
<tbody>
<#list task.sourceHistory.entries as entry>
<tr>
<td><a href="/internals/get/task-source?id=${entry.taskId}&timestamp=${entry.createdTimeMillis}"> ${entry.createdTime} </a></td>
</tr>
</#list>
</tbody>
</table>
</#if>
</#macro>

<@fragment/>
2 changes: 2 additions & 0 deletions src/staticContent/webui/templates/task_details.ftlh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<#import "/fragments/activations_modals.ftlh" as activations_modals_fragment>
<#import "/fragments/activations.ftlh" as activations_fragment>
<#import "/fragments/task_source_history.ftlh" as task_source_history_fragment>
<#import "/fragments/task_statistics.ftlh" as task_statistics_fragment>
<#import "/fragments/common_header.ftlh" as common_header_fragment>
<#import "/fragments/footer.ftlh" as footer_fragment>
Expand Down Expand Up @@ -56,6 +57,7 @@
<div id="task-activation-constructor-id" style="display:none;">${taskActivationConstructorId}</div>

<@activations_fragment.fragment/>
<@task_source_history_fragment.fragment/>
<@task_statistics_fragment.fragment/>
</div>
</div>
Expand Down

0 comments on commit 82412ac

Please sign in to comment.