Adding changes and code for terminology annotation support and integration of UMLS vocabulary

This commit is contained in:
hjkhjk54 2011-08-15 21:48:08 +00:00
parent a3f174f813
commit dc46b3e195
9 changed files with 1005 additions and 1 deletions

View file

@ -143,6 +143,10 @@
<rdf:Description rdf:about="http://vivoweb.org/ontology/core#webpage">
<display:listViewConfigFile rdf:datatype="http://www.w3.org/2001/XMLSchema#string">listViewConfig-webpage.xml</display:listViewConfigFile>
</rdf:Description>
</rdf:Description>
<rdf:Description rdf:about="http://vivoweb.org/ontology/core#terminologyAnnotation">
<display:listViewConfigFile rdf:datatype="http://www.w3.org/2001/XMLSchema#string">listViewConfig-terminologyAnnotation.xml</display:listViewConfigFile>
</rdf:Description>
</rdf:RDF>

View file

@ -1047,6 +1047,24 @@
<servlet-name>JSON Service</servlet-name>
<url-pattern>/dataservice</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>UMLSTerminology</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.servlet.UMLSTerminologyAnnotation</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UMLSTerminology</servlet-name>
<url-pattern>/UMLSTermsRetrieval</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ProcessTerminologyAnnotation</servlet-name>
<servlet-class>edu.cornell.mannlib.vitro.webapp.servlet.ProcessTerminologyController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ProcessTerminologyAnnotation</servlet-name>
<url-pattern>/edit/processTerminologyAnnotation</url-pattern>
</servlet-mapping>
<!-- Google Refine servlets begins -->

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<!-- See guidelines in vitro/doc/list_view_configuration_guidelines.txt -->
<list-view-config>
<query-select>
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX afn: &lt;http://jena.hpl.hp.com/ARQ/function#&gt;
SELECT ?terminologyContextNode ?referencedTerm ?entryTerm ?termLabel WHERE {
?subject ?property ?terminologyContextNode .
?terminologyContextNode core:referencedTerm ?referencedTerm .
?terminologyContextNode core:entryTerm ?entryTerm .
?terminologyContextNode core:termLabel ?termLabel .
} ORDER BY ?termLabel
</query-select>
<query-construct>
PREFIX core: &lt;http://vivoweb.org/ontology/core#&gt;
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
CONSTRUCT {
?subject ?property ?terminologyContextNode .
?terminologyContextNode core:referencedTerm ?referencedTerm .
?terminologyContextNode core:entryTerm ?entryTerm .
?terminologyContextNode core:termLabel ?termLabel .
} WHERE {
?subject ?property ?terminologyContextNode .
?terminologyContextNode core:referencedTerm ?referencedTerm .
?terminologyContextNode core:entryTerm ?entryTerm .
?terminologyContextNode core:termLabel ?termLabel .
}
</query-construct>
<template>propStatement-terminologyAnnotation.ftl</template>
</list-view-config>

View file

@ -0,0 +1,29 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
.terminology .column {
float:left;
padding-right:3px;
}
.terminology .row {
clear:both;
float:left;
border-bottom: 1px solid #5F6464;
}
.termLabel {
width:220px;
font-weight:bold;
}
.termType {
width: 40px;
}
.termDefinition{
width:400px;
}
form#addTerminologyForm {
display:none;
}

View file

@ -0,0 +1,239 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
var addTerminologyForm = {
/* *** Initial page setup *** */
onLoad: function() {
if (this.disableFormInUnsupportedBrowsers()) {
return;
}
this.mixIn();
this.initObjects();
this.initPage();
},
disableFormInUnsupportedBrowsers: function() {
var disableWrapper = $('#ie67DisableWrapper');
// Check for unsupported browsers only if the element exists on the page
if (disableWrapper.length) {
if (vitro.browserUtils.isIELessThan8()) {
disableWrapper.show();
$('.noIE67').hide();
return true;
}
}
return false;
},
mixIn: function() {
// Mix in the custom form utility methods
$.extend(this, vitro.customFormUtils);
// Get the custom form data from the page
$.extend(this, customFormData);
//test
alert(addTerminologyForm.UMLSCUIURL);
alert(addTerminologyForm.dataServiceUri);
},
// On page load, create references for easy access to form elements.
initObjects: function() {
this.form = $('#addTerminologyForm');
this.showFormButtonWrapper = $('#showAddForm');
this.submit = this.form.find(':submit');
this.cancel = this.form.find('.cancel');
//Add term
this.addTermButton = $('#showAddFormButton');
//section where results should be displayed
this.selectedTerm = $('#selectedTerm');
//input for search term form
this.searchTerm = $('#searchTerm');
this.searchSubmit = $('#searchButton');
//Hidden inputs for eventual submission
this.referencedTerm = $('#referencedTerm');
this.entryTerm = $('#entryTerm');
this.termLabel = $('#termLabel');
this.termType = $('#termType');
this.removeTermLinks = $('a.remove');
},
initPage: function() {
this.initTermData();
this.bindEventListeners();
},
bindEventListeners: function() {
this.searchSubmit.click(function() {
addTerminologyForm.submitSearchTerm();
return false;
});
this.form.submit(function() {
return addTerminologyForm.prepareSubmit();
});
this.addTermButton.click(function() {
addTerminologyForm.initForm();
});
this.removeTermLinks.click(function() {
addTerminologyForm.removeExistingTerm(this);
return false;
});
},
initForm: function() {
// Hide the button that shows the form
this.showFormButtonWrapper.hide();
this.clearSearchResults();
this.cancel.unbind('click');
this.cancel.bind('click', function() {
//show only list of existing terms and hide adding term form
addTerminologyForm.showTermListOnlyView();
return false;
});
// Show the form
this.form.show();
},
// On page load, associate data with each existing term element. Then we don't
// have to keep retrieving data from or modifying the DOM as we manipulate the
// authorships.
initTermData: function() {
$('.existingTerm').each(function(index) {
$(this).data(existingTermsData[index]);
$(this).data('position', index+1);
});
},
clearSearchResults:function() {
$('#selectedTerm').empty();
},
showTermListOnlyView: function() {
this.hideForm();
this.showFormButtonWrapper.show();
},
submitSearchTerm: function() {
//Get value of search term
var searchValue = this.searchTerm.val();
this.entryTerm.val(searchValue);
var dataServiceUrl = addTerminologyForm.dataServiceUrl + "?searchTerm=" + encodeURIComponent(searchValue);
$.getJSON(dataServiceUrl, function(results) {
if ( results.All.length == 0 ) {
} else {
//update existing content type with correct class group name and hide class group select again
var bestMatchResults = results["Best Match"];
var numberMatches = bestMatchResults.length;
var i;
//For each result, display
var htmlAdd = "";
if(numberMatches > 0) {
htmlAdd = "<ul class='dd' id='terms' name='terms'>";
htmlAdd+= addTerminologyForm.addResultsHeader();
for(i = 0; i < numberMatches; i++) {
var termResult = bestMatchResults[i];
var CUI = termResult.CUI;
var label = termResult.label;
var definition = termResult.definition;
var type = termResult.type;
var cuiURI = addTerminologyForm.UMLSCUIURL + CUI;
htmlAdd+= addTerminologyForm.generateIndividualTermDisplay(cuiURI, label, definition, type);
}
htmlAdd+= "</ul>";
} else {
htmlAdd+= "<p>No search results found.</p>";
}
$('#selectedTerm').html(htmlAdd);
}
});
},
addResultsHeader:function() {
var htmlAdd = "<li class='terminology'><div class='row'><span class='column termLabel'>Label (Type) </span><span class='column termDefinition'>Definition</span></div></li>";
return htmlAdd;
},
hideSearchResults:function() {
this.selectedTerm.hide();
},
prepareSubmit:function() {
var checkedElements = $("#CUI:checked");
var i;
var len = checkedElements.length;
var checkedTerm, checkedTermElement, termLabel, termType;
var referencedTerms = [];
var termLabels = [];
var termTypes = [];
checkedElements.each(function() {
checkedTermElement = $(this);
checkedTerm = checkedTermElement.val();
termType = checkedTermElement.attr("termType");
termLabel = checkedTermElement.attr("label");
referencedTerms.push(checkedTerm);
termLabels.push(termLabel);
termTypes.push(termType);
});
this.referencedTerm.val(referencedTerms);
this.termLabel.val(termLabels);
this.termType.val(termTypes);
return true;
},
generateIndividualTermDisplay: function(cuiURI, label, definition, type) {
var htmlAdd = "<li class='terminology'>" +
"<div class='row'>" +
"<span class='column termLabel'>" +
"<input type='checkbox' id='CUI' name='CUI' value='" + cuiURI + "' label='" + label + "' termType='" + type + "'/>" +
label + "( " + type + ")</span>" +
"<span class='column termDefinition'>" + definition + "</span>" +
"</div>" +
"</li>";
return htmlAdd;
}, removeExistingTerm: function(link) {
var removeLast = false,
message = 'Are you sure you want to remove this term?';
if (!confirm(message)) {
return false;
}
if ($(link)[0] === $('.remove:last')[0]) {
removeLast = true;
}
$.ajax({
url: $(link).attr('href'),
type: 'POST',
data: {
deletion: $(link).parents('.existingTerm').data('termNodeUri')
},
dataType: 'json',
context: link, // context for callback
complete: function(request, status) {
var existingTerm,
termNodeUri;
if (status === 'success') {
existingTerm = $(this).parents('.existingTerm');
existingTerm.fadeOut(400, function() {
var numTerms;
// For undo link: add to a deletedAuthorships array
// Remove from the DOM
$(this).remove();
// Actions that depend on the author having been removed from the DOM:
numTerms = $('.existingTerm').length; // retrieve the length after removing authorship from the DOM
});
} else {
alert('Error processing request: author not removed');
}
}
});
}
};
$(document).ready(function() {
addTerminologyForm.onLoad();
});

View file

@ -0,0 +1,286 @@
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
<%-- Custom form for adding terminology annotation
--%>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Arrays" %>
<%@ page import="java.util.Collections" %>
<%@ page import="com.hp.hpl.jena.rdf.model.Model" %>
<%@ page import="com.hp.hpl.jena.vocabulary.XSD" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.Individual" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.DataPropertyComparator" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.VitroRequest" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.JavaScript" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Css" %>
<%@ page import="org.apache.commons.lang.StringUtils" %>
<%@ page import="org.json.JSONObject" %>
<%@ page import="org.apache.commons.logging.Log" %>
<%@ page import="org.apache.commons.logging.LogFactory" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
<%@ taglib prefix="v" uri="http://vitro.mannlib.cornell.edu/vitro/tags" %>
<%!
public static Log log = LogFactory.getLog("edu.cornell.mannlib.vitro.webapp.jsp.edit.forms.terminologyAnnotation.jsp");
%>
<%
VitroRequest vreq = new VitroRequest(request);
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
vreq.setAttribute("defaultNamespace", ""); //empty string triggers default new URI behavior
vreq.setAttribute("stringDatatypeUriJson", MiscWebUtils.escape(XSD.xstring.toString()));
%>
<c:set var="vivoCore" value="http://vivoweb.org/ontology/core#" />
<c:set var="rdfs" value="<%= VitroVocabulary.RDFS %>" />
<c:set var="label" value="${rdfs}label" />
<c:set var="foaf" value="http://xmlns.com/foaf/0.1/" />
<c:set var="personClassUri" value="${foaf}Person" />
<%-- Unlike other custom forms, this form does not allow edits of existing authors, so there are no
SPARQL queries for existing values. --%>
<v:jsonset var="n3ForTerminology">
@prefix core: <${vivoCore}> .
?subject ?predicate ?terminologyContextNode .
?terminologyContextNode core:referencedTerm ?referencedTerm .
?terminologyContextNode core:entryTerm ?entryTerm .
?terminologyContextNode core:termLabel ?termLabel .
</v:jsonset>
<c:set var="returnPathAfterSubmit" value="/edit/editRequestDispatch.jsp?subjectUri=${subjectUri}&predicateUri=${predicateUri}" />
<c:set var="submitSearchUrl" value="/UMLSTermsRetrieval"/>
<c:url var="UMLSCUIURL" value="http://link.informatics.stonybrook.edu/umls/CUI/" />
<c:set var="editjson" scope="request">
{
"formUrl" : "${formUrl}",
"editKey" : "${editKey}",
"urlPatternToReturnTo" : "${returnPathAfterSubmit}",
"subject" : ["subject", "${subjectUriJson}" ],
"predicate" : ["predicate", "${predicateUriJson}" ],
"object" : ["terminologyContextNode", "${objectUriJson}", "URI" ],
"n3required" : [ "${n3ForTerminology}" ],
"n3optional" : [ ],
"newResources" : { "terminologyContextNode" : "${defaultNamespace}" },
"urisInScope" : { },
"literalsInScope": { },
"urisOnForm" : [ "referencedTerm" ],
"literalsOnForm" : [ "entryTerm", "termLabel" ],
"filesOnForm" : [ ],
"sparqlForLiterals" : { },
"sparqlForUris" : { },
"sparqlForExistingLiterals" : { },
"sparqlForExistingUris" : { },
"fields" : {
"referencedTerm" : {
"newResource" : "false",
"validators" : [ "nonempty" ],
"optionsType" : "UNDEFINED", //UNSURE WHAT TO KEEP HERE
"literalOptions" : [ ],
"predicateUri" : "",
"objectClassUri" : "",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${n3ForTerminology}" ]
},
"entryTerm" : {
"newResource" : "false",
"validators" : [ "nonempty" ],
"optionsType" : "UNDEFINED",
"literalOptions" : [ ],
"predicateUri" : "",
"objectClassUri" : "",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${n3ForTerminology}" ]
},
"termLabel" : {
"newResource" : "false",
"validators" : [ "nonempty" ],
"optionsType" : "UNDEFINED",
"literalOptions" : [ ],
"predicateUri" : "",
"objectClassUri" : "",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${n3ForTerminology}" ]
}
}
}
</c:set>
<%
log.debug(request.getAttribute("editjson"));
EditConfiguration editConfig = EditConfiguration.getConfigFromSession(session,request);
if (editConfig == null) {
editConfig = new EditConfiguration((String) request.getAttribute("editjson"));
EditConfiguration.putConfigInSession(editConfig,session);
}
//Specific validators can be included here
Model model = (Model) application.getAttribute("jenaOntModel");
String objectUri = (String) request.getAttribute("objectUri");
//for some reason we are comming from the add new and that is working
//but we also come from the edit, and that is not working.
editConfig.setObject(""); //this will force the edit config to always be an add, never an update
editConfig.prepareForNonUpdate(model); // we're only adding new, not editing existing
String subjectUri = vreq.getParameter("subjectUri");
String predicateUri = vreq.getParameter("predicateUri");
String vivoCore = "http://vivoweb.org/ontology/core#";
//Individual infoResource = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(subjectUri);
Individual subject = ((Individual) request.getAttribute("subject"));
vreq.setAttribute("subjectName", subject.getName());
//Get existing terminology annotations
List<Individual> terminologyAnnotationNodes = subject.getRelatedIndividuals(predicateUri);
List<String> customJs = new ArrayList<String>(Arrays.asList(JavaScript.JQUERY_UI.path(),
JavaScript.CUSTOM_FORM_UTILS.path(),
"/js/browserUtils.js",
"/edit/forms/js/addTerminology.js"
));
request.setAttribute("customJs", customJs);
//no custom css we know of yet
List<String> customCss = new ArrayList<String>(Arrays.asList(Css.JQUERY_UI.path(),
Css.CUSTOM_FORM.path(),
"/edit/forms/css/addTerminology.css"
));
request.setAttribute("customCss", customCss);
%>
<c:set var="title" value="<em>${subjectName}</em>"/>
<jsp:include page="${preForm}" />
<%-- DO NOT CHANGE IDS, CLASSES, OR HTML STRUCTURE ON THIS PAGE WITHOUT UNDERSTANDING THE IMPACT ON THE JAVASCRIPT! --%>
<h2>${title}</h2>
<%@ include file="unsupportedBrowserMessage.jsp" %>
<div class="noIE67">
<h3>Manage Terminology Annotations</h3>
<ul id="existingTerms" >
<%
int existingTermsCount = terminologyAnnotationNodes.size();
%>
<script type="text/javascript">
var existingTermsData = [];
</script>
<%
String termLabelUri = vivoCore + "termLabel";
for ( Individual termNode : terminologyAnnotationNodes ) {
request.setAttribute("termNodeUri", termNode.getURI());
//Get label and type only as mirroring authorship where labels but no links for individuals incoldued
DataPropertyStatement termLabelStatement = termNode.getDataPropertyStatement(termLabelUri);
String termLabel = termLabelStatement.getData();
request.setAttribute("termLabel", termLabel);
//Possible to get referenced term using object property statement?
%>
<li class="existingTerm">
<%-- span.author will be used in the next phase, when we display a message that the author has been
removed. That text will replace the a.authorName, which will be removed. --%>
<span class="term">
<%-- This span is here to assign a width to. We can't assign directly to the a.authorName,
for the case when it's followed by an em tag - we want the width to apply to the whole thing. --%>
<span class="termWrapper">
<span class="termLabel">
${termLabel}</span>
</span>
<c:url var="deleteTermHref" value="/edit/primitiveDelete" />
<a href="${deleteTermHref}" class="remove">Remove</a>
</span>
</li>
<script type="text/javascript">
existingTermsData.push({
"termNodeUri": "${termNodeUri}",
"termLabel": "${termLabel}"
});
</script>
<%
}
%>
</ul>
<% if (existingTermsCount == 0) { %>
<p>There are currently no terms specified.</p>
<% } %>
<div id="showAddForm">
<v:input type="submit" value="Add Term" id="showAddFormButton" name="showAddFormButton" cancel="true" cancelLabel="Return" cancelUrl="/individual" />
</div>
<form id="addTerminologyForm" class="customForm" action="<c:url value="/edit/processTerminologyAnnotation"/>" >
<h3>Search UMLS Terms</h3>
<p class="inline"><v:input type="text" id="searchTerm" label="Search UMLS" cssClass="acSelector" size="35" />
<input type="button" id="searchButton" name="searchButton" value="Search"/>
</p>
<input type="hidden" id="entryTerm" name="entryTerm" value="" /> <!-- Field value populated by JavaScript -->
<input type="hidden" id="referencedTerm" name="referencedTerm" value=""/> <!-- Field value populated by JavaScript -->
<input type="hidden" id="termLabel" name="termLabel" value="" /> <!-- Field value populated by JavaScript -->
<input type="hidden" id="termType" name="termType" value="" /> <!-- Field value populated by JavaScript -->
<div id="selectedTerm" name="selectedTerm" class="acSelection">
<%-- RY maybe make this a label and input field. See what looks best. --%>
<p class="inline">
</p>
<!-- Field value populated by JavaScript -->
</div>
<p class="submit"><v:input type="submit" id="submit" name="submit" value="Add Term" cancel="true" /></p>
</form>
</div>
<script type="text/javascript">
var customFormData = {
dataServiceUrl: '${submitSearchUrl}',
UMLSCUIURL: '${UMLSCUIURL}'
};
</script>
<jsp:include page="${postForm}"/>

View file

@ -0,0 +1,18 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Custom object property statement view for http://vivoweb.org/ontology/core#authorInAuthorship.
This template must be self-contained and not rely on other variables set for the individual page, because it
is also used to generate the property statement during a deletion.
-->
<#import "lib-sequence.ftl" as s>
<#import "lib-datetime.ftl" as dt>
<@showTerm statement />
<#-- Use a macro to keep variable assignments local; otherwise the values carry over to the
next statement -->
<#macro showTerm statement>
<a href="${statement.referencedTerm}">${statement.termLabel}</a>
</#macro>

View file

@ -0,0 +1,291 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.DefaultObjectWrapper;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
import javax.servlet.RequestDispatcher;
public class ProcessTerminologyController extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(ProcessTerminologyController.class);
private static final String submissionUrl = "/edit/processRdfForm2.jsp";
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
VitroRequest vreq = new VitroRequest(req);
try{
EditConfiguration editConfig = EditConfiguration.getConfigFromSession(req.getSession(), req);
//For query parameters, check whether CUI
String[] termsArray = new String[1];
String referencedTerms = vreq.getParameter("referencedTerm");
if(referencedTerms.indexOf(",") != -1) {
termsArray = referencedTerms.split(",");
}
int numberTerms = termsArray.length;
//if multiple values then need to process this differently by adding additional
//fields, assertions, etc. as well as changing the URL slightly
String url = "/edit/processRdfForm2.jsp?" + vreq.getQueryString();
if(numberTerms > 1) {
//Add new resources, i.e. the additional terminology context nodes
addNewResources(editConfig, vreq, numberTerms);
//Add N3Required
addN3Required(editConfig,vreq, numberTerms);
//Add URIs on Form and Add Literals On Form
addLiteralsAndUrisOnForm(editConfig, vreq, numberTerms);
//Add fields
addFields(editConfig, vreq, numberTerms);
//Generate new url which will map input fields to value
url = generateUrl(editConfig, vreq);
}
RequestDispatcher dispatcher = req.getRequestDispatcher(url);
dispatcher.forward(req, resp);
} catch(Exception ex) {
log.error("error occurred in servlet", ex);
}
}
private String generateUrl(EditConfiguration editConfig, VitroRequest vreq) {
//Get original url and query string
String newUrl = "/edit/processRdfForm2.jsp?" + vreq.getQueryString();
//Iterate through the terms and include appropriate values
Map <String,String[]> queryParameters = null;
queryParameters = vreq.getParameterMap();
//Use same query parameters to forward
String termParam = vreq.getParameter("referencedTerm");
String labelParam = vreq.getParameter("termLabel");
String typeParam = vreq.getParameter("termType");
if(!labelParam.contains(",")){
log.error("Multiple labels are not being sent back, this is an error");
}
if(!typeParam.contains(",")) {
log.error("Multiple types are not being sent back, this is an error");
}
String[] termsArray = termParam.split(",");
String[] termLabels = labelParam.split(",");
String[] termTypes = typeParam.split(",");
String entryTerm = vreq.getParameter("entryTerm");
int numberParameters = termsArray.length;
int index;
String referencedBase = "referencedTerm";
String labelBase = "termLabel";
String termBase = "termType";
//Should already include entry term so no need to include here
//newUrl += "&entryTerm=" + URLEncoder.encode(entryTerm);
//Add entry
for(index = 1; index <= numberParameters; index++) {
String referencedInputName = referencedBase + index;
String termLabelInputName = labelBase + index;
String termTypeInputName =termBase + index;
//array is set to start at 0, not 1
String referencedTerm = termsArray[index - 1];
String termLabel = termLabels[index - 1];
String termType = termTypes[index - 1];
newUrl += "&" + referencedInputName + "=" + URLEncoder.encode(referencedTerm);
newUrl += "&" + termLabelInputName + "=" + URLEncoder.encode(termLabel);
newUrl += "&" + termTypeInputName + "=" + URLEncoder.encode(termType);
}
return newUrl;
}
private void addNewResources(EditConfiguration editConfig, VitroRequest vreq, int numberTerms) {
Map<String, String> newResources = new HashMap<String, String>();
//Based on number of terms, add new
int n;
String defaultNamespace = "";
String base = "terminologyContextNode";
for(n = 1; n <= numberTerms; n++) {
String newNode = base + n;
newResources.put(newNode, defaultNamespace);
}
//TODO: Check if below is required as this is a reference
editConfig.setNewResources(newResources);
}
/*
* "referencedTerm" : {
"newResource" : "false",
"validators" : [ "nonempty" ],
"optionsType" : "UNDEFINED", //UNSURE WHAT TO KEEP HERE
"literalOptions" : [ ],
"predicateUri" : "",
"objectClassUri" : "",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${n3ForTerminology}" ]
},
"entryTerm" : {
"newResource" : "false",
"validators" : [ "nonempty" ],
"optionsType" : "UNDEFINED",
"literalOptions" : [ ],
"predicateUri" : "",
"objectClassUri" : "",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${n3ForTerminology}" ]
},
"termLabel" : {
"newResource" : "false",
"validators" : [ "nonempty" ],
"optionsType" : "UNDEFINED",
"literalOptions" : [ ],
"predicateUri" : "",
"objectClassUri" : "",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${n3ForTerminology}" ]
}
*/
private void addFields(EditConfiguration editConfig, VitroRequest vreq, int numberTerms) {
Map<String, Field> fieldMap = new HashMap<String, Field>();
int index;
String referencedBase = "referencedTerm";
String entryBase = "entryTerm";
String labelBase = "termLabel";
//Entry only needs to be added once
fieldMap.put(entryBase, generateField(editConfig));
//First one already included so add new ones here
for(index = 1; index <= numberTerms; index++) {
int suffix = index;
String referencedTerm = referencedBase + suffix;
String label = labelBase + suffix;
//need to add termType
//Generate Field for each
fieldMap.put(referencedTerm, generateField(editConfig));
fieldMap.put(label, generateField(editConfig));
//termType would also go in here
}
editConfig.setFields(fieldMap);
}
/*
"newResource" : "false",
"validators" : [ "nonempty" ],
"optionsType" : "UNDEFINED",
"literalOptions" : [ ],
"predicateUri" : "",
"objectClassUri" : "",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${n3ForTerminology}" ]*/
private Field generateField(EditConfiguration editConfig) {
List<String> n3Required = editConfig.getN3Required();
Field field = new Field();
field.setNewResource(false);
List<String> validators = new ArrayList<String>();
validators.add("nonempty");
field.setValidators(validators);
field.setOptionsType("UNDEFINED");
field.setLiteralOptions(new ArrayList<List<String>>());
field.setPredicateUri("");
field.setObjectClassUri("");
field.setRangeDatatypeUri("");
field.setRangeLang("");
field.setAssertions(n3Required);
return field;
}
//Original uris and literals included:
/*
* "urisOnForm" : [ "referencedTerm" ],
"literalsOnForm" : [ "entryTerm", "termLabel" ],
*/
private void addLiteralsAndUrisOnForm(EditConfiguration editConfig,
VitroRequest vreq, int numberTerms) {
List<String> urisOnForm = new ArrayList<String>();
List<String> literalsOnForm = new ArrayList<String>();
int index;
String referencedBase = "referencedTerm";
String entryBase = "entryTerm";
String labelBase = "termLabel";
//entry term needs to be added only once
literalsOnForm.add(entryBase);
//First one already included so add new ones here
for(index = 1; index <= numberTerms; index++) {
int suffix = index;
String referencedTerm = referencedBase + suffix;
String label = labelBase + suffix;
urisOnForm.add(referencedTerm);
literalsOnForm.add(label);
}
editConfig.setUrisOnform(urisOnForm);
editConfig.setLiteralsOnForm(literalsOnForm);
}
//original n3 required is of this format
/*@prefix core: <${vivoCore}> .
?subject ?predicate ?terminologyContextNode .
?terminologyContextNode core:referencedTerm ?referencedTerm .
?terminologyContextNode core:entryTerm ?entryTerm .
?terminologyContextNode core:termLabel ?termLabel .
*/
private void addN3Required(EditConfiguration editConfig, VitroRequest vreq, int numberTerms) {
//List<String> n3Required = editConfig.getN3Required();
List<String> n3Required = new ArrayList<String>();
int index;
String nodeBase = "?terminologyContextNode";
String referencedBase = "?referencedTerm";
//there's only one entry term in this case
String entryBase = "?entryTerm";
String labelBase = "?termLabel";
String prefixStr = "@prefix core: <http://vivoweb.org/ontology/core#> .";
//First one already included so add new ones here
for(index = 1; index <= numberTerms; index++) {
int suffix = index;
String node = nodeBase + suffix;
String referencedTerm = referencedBase + suffix;
String label = labelBase + suffix;
String n3String = prefixStr;
n3String += "?subject ?predicate " + node + " . " +
node + " core:entryTerm " + entryBase + " . " +
node + " core:termLabel " + label + " . " +
node + " core:referencedTerm " + referencedTerm + " . ";
n3Required.add(n3String);
}
editConfig.setN3Required(n3Required);
}
}

View file

@ -0,0 +1,76 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.DefaultObjectWrapper;
public class UMLSTerminologyAnnotation extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(UMLSTerminologyAnnotation.class);
private static final String submissionUrl = "http://link.informatics.stonybrook.edu/MeaningLookup/MlServiceServlet?";
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
VitroRequest vreq = new VitroRequest(req);
try{
//Get parameter
String entryText = vreq.getParameter("searchTerm");
System.out.println("Entry text is " + entryText);
//TODO: Find a non-deprecated mechanism to do so
String dataUrl = submissionUrl + "textToProcess=" + URLEncoder.encode(entryText) + "&format=json";
try{
ServletOutputStream sos = resp.getOutputStream();
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json;charset=UTF-8");
URL rss = new URL(dataUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(rss.openStream()));
String inputLine;
while((inputLine = in.readLine()) != null) {
sos.println(inputLine);
}
in.close();
} catch(Exception ex) {
log.error("error occurred in servlet", ex);
}
}catch(Exception ex){
log.warn(ex,ex);
}
}
}