Massive work done on File Harvest

This commit is contained in:
mbarbier 2011-06-28 20:33:51 +00:00
parent 730b237e84
commit d5965b8112
4 changed files with 154 additions and 36 deletions

View file

@ -15,6 +15,9 @@
function doHarvest()
{
document.getElementById("harvestButton").disabled = true;
document.getElementById("harvestButtonHelpText").innerHTML = "Please wait while your data is harvested.";
var request = createRequest();
request.onreadystatechange=function() {
if(request.readyState == 4 && request.status == 200) {
@ -53,14 +56,19 @@
request.send("${paramMode}=${modeCheckStatus}");
} else {
var importedGrants = document.getElementById("importedGrants")
var linkHeader = document.getElementById("linkHeader");
linkHeader.style.display = "inline";
var importedItems = document.getElementById("importedItems")
for(var i = 0; i < json.newlyAddedUrls.length; i++) {
var newLi = document.createElement("li");
newLi.innerHTML = "<a href=\"" + json.newlyAddedUrls[i] + "\">" + json.newlyAddedUris[i] + "</a>";
importedGrants.appendChild(newLi);
importedItems.appendChild(newLi);
}
document.getElementById("harvestButtonHelpText").innerHTML = "Harvest complete. For another, please refresh the page.";
}
}
@ -115,9 +123,10 @@
//document.getElementById("responseArea").innerHTML = response;
}
function init()
{
document.getElementById("harvestButton").disabled = false;
document.getElementById("${paramFirstUpload}").value = "true";
document.getElementById("fileUploadForm").onsubmit = function()
{
@ -130,6 +139,7 @@
}
}
window.onload = init;
</script>
@ -161,7 +171,7 @@
<h4 class="testfile-step-subheader">Download template</h4>
<form id="downloadTemplateForm" method="post" action=${postTo}>
<input type="hidden" id="${paramMode}" name="${paramMode}" value="${modeDownloadTemplate}" />
<p><input type="submit" name="submit" value="Download" style="margin-right:10px" />We are providing a helpful template file for you to download.</p>
<p><input type="submit" name="submit" value="Download" style="margin-right:10px" />${jobSpecificDownloadHelp}</p>
</form>
</div>
<div class="clearBothDiv" />
@ -172,8 +182,7 @@
<h4 class="testfile-step-subheader">Fill in data <a style="font-size:smaller;margin-left:10px" onclick="toggleCsvHelp();return false;" href="#">Help</a></h4>
<div id="csvHelp-collapsible" style="display:none">
<div id="csvHelp-indented" style="margin-left:20px;font-size:smaller">
<p>A CSV, or <b>C</b>omma-<b>S</b>eparated <b>V</b>alues file, is a method of storing tabular data in plain text. The first line of a CSV file contains header information, while each subsequent line contains a data record.</p>
<p>The template we provide contains only the header, which you will then fill in accordingly. For example, if the template contains the text "firstName,lastName", then you might add two more lines, "John,Doe" and "Jane,Public".</p>
${jobSpecificFillInHelp}
</div>
</div>
<p>Fill in the template with your data. You may fill in multiple templates if you wish to harvest multiple files at once.</p>
@ -219,7 +228,7 @@
</ul>
</div>
</div>
<p><input type="button" value="Harvest" style="margin-right:10px" onclick="doFunStuff();" />Click the button to harvest your file(s).</p>
<p><input type="button" name="harvestButton" id="harvestButton" value="Harvest" style="margin-right:10px" onclick="doFunStuff();" /><span id="harvestButtonHelpText">Click the button to harvest your file(s).</span></p>
</div>
<div class="clearBothDiv" />
</div>
@ -230,11 +239,11 @@
<div id="step5-inner" class="testfile-step-body">
<h4 class="testfile-step-subheader">View results</h4>
<div id="progress">
<textarea cols="100" rows="50" readonly="readonly" id="progressTextArea"></textarea>
<textarea cols="100" rows="20" readonly="readonly" id="progressTextArea"></textarea>
</div>
<div id="summary">
<h5>${jobSpecificLinkHeader}</h5>
<ul id="importedGrants">
<h5 id="linkHeader" style="display:none">${jobSpecificLinkHeader}</h5>
<ul id="importedItems">
</ul>
</div>
</div>

View file

@ -23,6 +23,66 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
*/
class CsvFileHarvestJob implements FileHarvestJob {
/**
* Contains constant constructor inputs for CsvFileHarvestJob
* @author mbarbieri
*/
public enum JobType {
GRANT("csvGrant", "granttemplate.csv", "testCSVtoRDFgrant.sh", "Grant", "Imported Grants", new String[] {"http://vivoweb.org/ontology/core#Grant"}),
PERSON("csvPerson", "persontemplate.csv", "testCSVtoRDFpeople.sh", "Person", "Imported Persons", new String[] {"http://xmlns.com/foaf/0.1/Person"});
public final String httpParameterName;
private final String templateFileName;
private final String scriptFileName;
private final String friendlyName;
private final String linkHeader;
private final String[] rdfTypesForLinks;
/**
* Determines if there is a JobType with the specified HTTP parameter name.
* @param httpParameterName the HTTP parameter name to look for a Job Type for
* @return true if there is such a JobType, false otherwise
*/
public static boolean containsTypeWithHttpParameterName(String httpParameterName) {
return (getByHttpParameterName(httpParameterName) != null);
}
/**
* Returns the JobType with the specified HTTP parameter name. This is essentially a string identifier for the job type. This
* method accepts nulls, returning null in that case.
* @param httpParameterName the HTTP parameter name to find the job for
* @return the JobType with the specified HTTP parameter name, or null if there is none or httpParameterName was null
*/
public static JobType getByHttpParameterName(String httpParameterName) {
JobType returnValue = null;
if(httpParameterName != null) {
JobType[] values = JobType.values();
for(JobType jobType : values) {
if(jobType.httpParameterName.equalsIgnoreCase(httpParameterName)) {
returnValue = jobType;
break;
}
}
}
return returnValue;
}
private JobType(String httpParameterName, String templateFileName, String scriptFileName, String friendlyName, String linkHeader, String[] rdfTypesForLinks) {
this.httpParameterName = httpParameterName;
this.templateFileName = templateFileName;
this.scriptFileName = scriptFileName;
this.friendlyName = friendlyName;
this.linkHeader = linkHeader;
this.rdfTypesForLinks = Arrays.copyOf(rdfTypesForLinks, rdfTypesForLinks.length);
}
private CsvFileHarvestJob constructCsvFileHarvestJob(VitroRequest vreq, String namespace) {
return new CsvFileHarvestJob(vreq, this.templateFileName, this.scriptFileName, namespace, this.friendlyName, this.linkHeader, this.rdfTypesForLinks);
}
}
/**
* Logger.
*/
@ -53,22 +113,33 @@ class CsvFileHarvestJob implements FileHarvestJob {
*/
private final String friendlyName;
/**
* A heading to be shown above the area where links to profiles of newly-harvested entities are listed.
*/
private final String linkHeader;
/**
* An array of rdf:type values which will be used for links.
*/
private final String[] rdfTypesForLinks;
public static CsvFileHarvestJob createJob(JobType jobType, VitroRequest vreq, String namespace) {
return jobType.constructCsvFileHarvestJob(vreq, namespace);
}
/**
* Constructor.
* @param templateFileName just the name of the template file. The directory is assumed to be standard.
*/
public CsvFileHarvestJob(VitroRequest vreq, String templateFileName, String scriptFileName, String namespace, String friendlyName, String[] rdfTypesForLinks) {
private CsvFileHarvestJob(VitroRequest vreq, String templateFileName, String scriptFileName, String namespace, String friendlyName, String linkHeader, String[] rdfTypesForLinks) {
this.vreq = vreq;
this.templateFile = new File(getTemplateFileDirectory() + templateFileName);
this.scriptFile = new File(getScriptFileDirectory() + scriptFileName);
log.error(getTemplateFileDirectory() + templateFileName);
this.namespace = namespace;
this.friendlyName = friendlyName;
this.linkHeader = linkHeader;
this.rdfTypesForLinks = Arrays.copyOf(rdfTypesForLinks, rdfTypesForLinks.length);
}
@ -252,14 +323,7 @@ class CsvFileHarvestJob implements FileHarvestJob {
@Override
public String getLinkHeader() {
return "Imported " + pluralize(this.friendlyName);
}
private String pluralize(String input) {
String plural = input + "s";
if(input.endsWith("s") || input.endsWith("x"))
plural = input + "es";
return plural;
return this.linkHeader;
}
@Override
@ -272,6 +336,20 @@ class CsvFileHarvestJob implements FileHarvestJob {
return Arrays.copyOf(this.rdfTypesForLinks, this.rdfTypesForLinks.length);
}
@Override
public String getTemplateDownloadHelp() {
return "Click here to download a template file to assist you with harvesting the data.";
}
@Override
public String getTemplateFillInHelp() {
String newline = "\n";
String help = "";
help += "<p>A CSV, or <b>C</b>omma-<b>S</b>eparated <b>V</b>alues file, is a method of storing tabular data in plain text. The first line of a CSV file contains header information, while each subsequent line contains a data record.</p>" + newline;
help += "<p>The template we provide contains only the header, which you will then fill in accordingly. For example, if the template contains the text \"firstName,lastName\", then you might add two more lines, \"John,Doe\" and \"Jane,Public\".</p>" + newline;
return help;
}
}

View file

@ -55,5 +55,17 @@ interface FileHarvestJob {
* @return an array of types to be used in links
*/
String[] getRdfTypesForLinks();
/**
* Get the HTML to be shown on the page immediately next to the "Download" button for the template.
* @return the HTML to be shown on the page immediately next to the "Download" button for the template.
*/
String getTemplateDownloadHelp();
/**
* Get the HTML to be shown in the collapsible "Help" area in the "Fill in data" section of the page.
* @return the HTML to be shown in the collapsible "Help" area in the "Fill in data" section of the page.
*/
String getTemplateFillInHelp();
}

View file

@ -58,15 +58,15 @@ public class TestFileController extends FreemarkerHttpServlet {
private static final String POST_TO = "/vivo/harvester/harvest";
private static final String JOB_CSV_GRANT = "csvGrant";
private static final String JOB_CSV_PERSON = "csvPerson";
private static final String MODE_HARVEST = "harvest";
private static final String MODE_CHECK_STATUS = "checkStatus";
private static final String MODE_DOWNLOAD_TEMPLATE = "template";
private static final List<String> knownJobs = Arrays.asList(JOB_CSV_GRANT.toLowerCase(), JOB_CSV_PERSON.toLowerCase());
/**
* A list of known job parameters (that is, "job=" values from the query string which we will accept from the browser).
* This should be filled in the static initializer and then never written to again.
*/
private static final List<String> knownJobs = new ArrayList<String>();
/**
@ -96,6 +96,26 @@ public class TestFileController extends FreemarkerHttpServlet {
public static final String PATH_TO_HARVESTER_SCRIPTS = "scripts/";
static {
fillKnownJobTypesList();
}
/**
* Fill the known job types list. Any time a new job type is added, we need to make sure this method is adding it to the list.
* By "new job type" is meant a new "job=" parameter that we understand when we see it in the query string. This typically means
* we have also handled seeing this parameter in the getJob() method of this class.
*
* The exception to all this is a new CSV job, which is entirely handled by adding a new CsvFileHarvestJob.JobType enum value. This
* method as well as this class's getJob() method already handle the rest.
*/
private static void fillKnownJobTypesList() {
//fill known CSV job types
CsvFileHarvestJob.JobType[] csvFileHarvestJobTypes = CsvFileHarvestJob.JobType.values();
for(CsvFileHarvestJob.JobType csvFileHarvestJobType : csvFileHarvestJobTypes) {
knownJobs.add(csvFileHarvestJobType.httpParameterName.toLowerCase());
}
}
@Override
@ -120,8 +140,10 @@ public class TestFileController extends FreemarkerHttpServlet {
body.put("job", job);
body.put("jobKnown", jobKnown);
body.put("postTo", POST_TO + "?" + PARAMETER_JOB + "=" + job);
body.put("jobSpecificHeader", jobObject.getPageHeader());
body.put("jobSpecificLinkHeader", jobObject.getLinkHeader());
body.put("jobSpecificHeader", (jobObject != null) ? jobObject.getPageHeader() : "");
body.put("jobSpecificLinkHeader", (jobObject != null) ? jobObject.getLinkHeader() : "");
body.put("jobSpecificDownloadHelp", (jobObject != null) ? jobObject.getTemplateDownloadHelp() : "");
body.put("jobSpecificFillInHelp", (jobObject != null) ? jobObject.getTemplateFillInHelp() : "");
return new TemplateResponseValues(TEMPLATE_DEFAULT, body);
} catch (Throwable e) {
log.error(e, e);
@ -175,13 +197,10 @@ public class TestFileController extends FreemarkerHttpServlet {
FileHarvestJob job = null;
//todo: complete
if(jobParameter == null)
log.error("No job specified.");
else if(jobParameter.equalsIgnoreCase(JOB_CSV_GRANT))
job = new CsvFileHarvestJob(vreq, "granttemplate.csv", "testCSVtoRDFgrant.sh", namespace, "Grant", new String[] {"http://vivoweb.org/ontology/core#Grant"});
else if(jobParameter.equalsIgnoreCase(JOB_CSV_PERSON))
job = new CsvFileHarvestJob(vreq, "persontemplate.csv", "testCSVtoRDFpeople.sh", namespace, "Person", new String[] {"http://xmlns.com/foaf/0.1/Person"});
else if(CsvFileHarvestJob.JobType.containsTypeWithHttpParameterName(jobParameter)) //check if this is a CSV job
job = CsvFileHarvestJob.createJob(CsvFileHarvestJob.JobType.getByHttpParameterName(jobParameter), vreq, namespace);
else
log.error("Invalid job: " + jobParameter);