Skip to content

Commit

Permalink
Merge pull request #131 from DenisKnoepfle/master
Browse files Browse the repository at this point in the history
Add automatic fetch of results in navigator (#116)
  • Loading branch information
DenisKnoepfle committed Oct 14, 2014
2 parents 8b973e9 + 72c07c1 commit 00a3c03
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public class DynamicSpotterRunJob extends Job {

private final IProject project;
private final long jobId;
private final long timestamp;
private final Set<String> processedProblems;
private Map.Entry<String, DiagnosisProgress> currentProblem;

Expand All @@ -81,7 +80,6 @@ public DynamicSpotterRunJob(IProject project, long jobId, long timestamp) {

this.project = project;
this.jobId = jobId;
this.timestamp = timestamp;
this.processedProblems = new HashSet<>();

ImageDescriptor imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(Activator.PLUGIN_ID, ICON_PATH);
Expand All @@ -95,7 +93,7 @@ public DynamicSpotterRunJob(IProject project, long jobId, long timestamp) {
setPriority(LONG);
setUser(true);

if (!JobsContainer.registerJobId(project, jobId)) {
if (!JobsContainer.registerJobId(project, jobId, timestamp)) {
DialogUtils.openError(RunHandler.DIALOG_TITLE,
"There was an error when saving the job id. You may not access the results of the diagnosis run.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
Expand All @@ -42,6 +44,7 @@ public class JobsContainer implements Serializable {
private static final long serialVersionUID = 2437447304864394397L;

private final Set<Long> jobIds = new HashSet<>();
private final Map<Long, Long> timestamps = new HashMap<>();

/**
* Returns <code>true</code> if the id is included, otherwise
Expand All @@ -56,6 +59,20 @@ public boolean hasJobId(Long jobId) {
return jobIds.contains(jobId);
}

/**
* Returns the timestamp that corresponds to the given job id.
*
* @param jobId
* the job id the timestamp shall be returned for
* @return the corresponding timestamp
*/
public Long getTimestamp(Long jobId) {
if (!jobIds.contains(jobId)) {
throw new IllegalArgumentException("The given job id is not registered");
}
return timestamps.get(jobId);
}

/**
* Returns an array of all stored job ids.
*
Expand All @@ -79,9 +96,12 @@ public int count() {
*
* @param jobId
* the id to add
* @param timestamp
* the corresponding timestamp
*/
public void addJobId(Long jobId) {
public void addJobId(Long jobId, Long timestamp) {
jobIds.add(jobId);
timestamps.put(jobId, timestamp);
}

/**
Expand All @@ -91,13 +111,15 @@ public void addJobId(Long jobId) {
* the id to remove
*/
public void removeJobId(Long jobId) {
timestamps.remove(jobId);
jobIds.remove(jobId);
}

/**
* Clears all job ids.
*/
public void reset() {
timestamps.clear();
jobIds.clear();
}

Expand All @@ -108,33 +130,49 @@ public void reset() {
* the project the id belongs to
* @param jobId
* the id to register
* @param timestamp
* the corresponding timestamp
* @return <code>true</code> on success, otherwise <code>false</code>
*/
public static boolean registerJobId(IProject project, long jobId) {
public static boolean registerJobId(IProject project, long jobId, long timestamp) {
boolean success = false;
synchronized (JobsContainer.jobMonitor) {
JobsContainer jobsContainer = readJobsContainer(project);
jobsContainer.addJobId(jobId);
jobsContainer.addJobId(jobId, timestamp);
success = writeJobsContainer(project, jobsContainer);
}
return success;
}

/**
* Returns the job ids that belong to the given project.
* Removes the given job id for the project.
*
* @param project
* the project whose job ids should be returned
* @return array of related job ids
* the project the id belongs to
* @param jobId
* the id to remove
* @return <code>true</code> on success, otherwise <code>false</code>
*/
public static Long[] getJobIds(IProject project) {
public static boolean removeJobId(IProject project, long jobId) {
boolean success = false;
synchronized (JobsContainer.jobMonitor) {
JobsContainer jobsContainer = readJobsContainer(project);
return jobsContainer.getJobIds();
jobsContainer.removeJobId(jobId);
success = writeJobsContainer(project, jobsContainer);
}
return success;
}

private static JobsContainer readJobsContainer(IProject project) {
/**
* Retrieves the current job container for the given project. In case the
* file does not exist or an error occurs while reading it an empty
* container is returned.
*
* @param project
* the project the container should be retrieved for
* @return the corresponding job container or an empty one
*/
public static JobsContainer readJobsContainer(IProject project) {
String fileName = project.getFile(FileManager.JOBS_CONTAINER_FILENAME).getLocation().toString();
File file = new File(fileName);
JobsContainer jobsContainer = new JobsContainer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ private String getLabel(Viewer viewer, Object e1) {
IBaseLabelProvider prov = ((ContentViewer) viewer).getLabelProvider();
if (prov instanceof ILabelProvider) {
ILabelProvider lprov = (ILabelProvider) prov;
// TODO: convert between timestamp and nice date representation
// for SpotterProjectRunResult elements
name1 = lprov.getText(e1);
} else {
name1 = e1.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,27 @@
package org.spotter.eclipse.ui.navigator;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.swt.graphics.Image;
import org.lpe.common.util.LpeFileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spotter.eclipse.ui.Activator;
import org.spotter.eclipse.ui.ServiceClientWrapper;
import org.spotter.eclipse.ui.jobs.JobsContainer;
import org.spotter.eclipse.ui.util.DialogUtils;
import org.spotter.shared.configuration.FileManager;
import org.spotter.shared.result.ResultsLocationConstants;
import org.spotter.shared.result.model.ResultsContainer;

/**
* An element that represents the results node.
Expand Down Expand Up @@ -125,39 +134,85 @@ public void refreshChildren() {
}

private ISpotterProjectElement[] initializeChildren(IProject iProject) {
String defaultResultsDir = FileManager.DEFAULT_RESULTS_DIR_NAME;
IFolder resDir = iProject.getFolder(defaultResultsDir);
IFolder resDir = iProject.getFolder(FileManager.DEFAULT_RESULTS_DIR_NAME);

if (!resDir.isSynchronized(IResource.DEPTH_INFINITE)) {
try {
resDir.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
LOGGER.warn("Failed to refresh results directory");
String msg = "Failed to refresh results directory.";
LOGGER.warn(msg);
DialogUtils.openWarning(msg);
return SpotterProjectParent.NO_CHILDREN;
}
}

File res = new File(resDir.getLocation().toString());
List<File> runFolders = new ArrayList<>();
ISpotterProjectElement[] elements = SpotterProjectParent.NO_CHILDREN;
return synchronizeRunResults(iProject, resDir.getLocation().toString());
}

private ISpotterProjectElement[] synchronizeRunResults(IProject iProject, String resultsLocation) {
File res = new File(resultsLocation);
List<ISpotterProjectElement> elements = new ArrayList<>();
ServiceClientWrapper client = Activator.getDefault().getClient(iProject.getName());

if (!res.exists() || !res.isDirectory()) {
DialogUtils.openWarning("The project's results folder is missing or corrupted!");
} else {
boolean connected = client.testConnection(false);
if (!connected) {
DialogUtils.openAsyncWarning("No connection to DS service! New results cannot be fetched from the server.");
}
JobsContainer jobsContainer = JobsContainer.readJobsContainer(iProject);

if (res.exists() && res.isDirectory()) {
File[] files = res.listFiles();
for (File file : files) {
if (file.isDirectory()) {
runFolders.add(file);
for (Long jobId : jobsContainer.getJobIds()) {
SpotterProjectRunResult runResult = processJobId(jobId, connected, client, jobsContainer,
resultsLocation, iProject);
if (runResult != null) {
elements.add(runResult);
}
}
}

return elements.toArray(new ISpotterProjectElement[elements.size()]);
}

private SpotterProjectRunResult processJobId(Long jobId, boolean connected, ServiceClientWrapper client,
JobsContainer jobsContainer, String resultsLocation, IProject iProject) {
if (connected && client.isRunning(true) && jobId.equals(client.getCurrentJobId())) {
LOGGER.debug("Ignore job " + jobId + " because it is currently running");
return null;
}

elements = new ISpotterProjectElement[runFolders.size()];
int i = 0;
for (File runFolder : runFolders) {
IFolder runResultFolder = iProject.getFolder(defaultResultsDir + File.separator + runFolder.getName());
elements[i++] = new SpotterProjectRunResult(this, runFolder.getName(), runResultFolder);
Long timestamp = jobsContainer.getTimestamp(jobId);
SimpleDateFormat dateFormat = new SimpleDateFormat("yy-MM-dd_HH-mm-ss-SSS");
String formattedTimestamp = dateFormat.format(new Date(timestamp));

String fileName = resultsLocation + "/" + formattedTimestamp;
File file = new File(fileName);
boolean success = file.exists();
if (!success && connected) {
// try to fetch data from server
ResultsContainer resultsContainer = client.requestResults(jobId.toString());
if (resultsContainer != null && file.mkdir()) {
String resultsFile = fileName + "/" + ResultsLocationConstants.RESULTS_SERIALIZATION_FILE_NAME;
try {
LpeFileUtils.writeObject(resultsFile, resultsContainer);
success = true;
} catch (IOException e) {
String msg = "Error while saving fetched results for job " + jobId + "!";
DialogUtils.openError(msg);
LOGGER.error(msg + " Cause: {}", e.toString());
}
}
}

return elements;
if (success) {
IFolder runResultFolder = iProject.getFolder(FileManager.DEFAULT_RESULTS_DIR_NAME + "/"
+ formattedTimestamp);
return new SpotterProjectRunResult(this, jobId, timestamp, runResultFolder);
} else {
return null;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.spotter.eclipse.ui.Activator;
import org.spotter.eclipse.ui.jobs.JobsContainer;
import org.spotter.eclipse.ui.util.DialogUtils;
import org.spotter.eclipse.ui.view.ResultsView;

Expand All @@ -47,31 +48,35 @@ public class SpotterProjectRunResult implements IOpenableProjectElement, IDeleta
private final ISpotterProjectElement parent;
private final IFolder resultFolder;
private Image image;
private final long jobId;
private final long timestamp;
private final String elementName;

/**
* Creates a new instance of this element.
*
* @param parent
* the parent element
* @param elementName
* the name of the element
* @param jobId
* the corresponding job id of this run result
* @param timestamp
* the corresponding timestamp of this run result
* @param resultFolder
* the result folder that is represented by this node
*/
public SpotterProjectRunResult(ISpotterProjectElement parent, String elementName, IFolder resultFolder) {
public SpotterProjectRunResult(ISpotterProjectElement parent, long jobId, long timestamp, IFolder resultFolder) {
this.parent = parent;
this.elementName = elementName;
this.jobId = jobId;
this.timestamp = timestamp;

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd (HH:mm:ss)");
this.elementName = dateFormat.format(new Date(timestamp));

this.resultFolder = resultFolder;
}

@Override
public String getText() {
long timestamp = System.currentTimeMillis(); // TODO: replaced later by saved timestamp
Date date = new Date(timestamp);
SimpleDateFormat dateFormat = new SimpleDateFormat("yy-MM-dd (HH:mm:ss)");
String readableTimestamp = dateFormat.format(date);
//return readableTimestamp;
return elementName;
}

Expand All @@ -84,6 +89,13 @@ public Image getImage() {
return image;
}

/**
* @return the corresponding timestamp of this run result
*/
public long getTimestamp() {
return timestamp;
}

/**
* @return the result folder this element is linked to
*/
Expand Down Expand Up @@ -156,6 +168,11 @@ public void delete() {

ResultsView.reset(resultFolder);
resultFolder.delete(true, null);
// clear job id
if (!JobsContainer.removeJobId(getProject(), jobId)) {
DialogUtils
.openError("There was an error while updating the project's job ids. The results of the corresponding id will be fetched again.");
}
// update navigator viewer
((SpotterProjectResults) getParent()).refreshChildren();
TreeViewer viewer = Activator.getDefault().getNavigatorViewer();
Expand Down
Loading

0 comments on commit 00a3c03

Please sign in to comment.