updates for data property editing- NIHVIVO-3386
This commit is contained in:
parent
a4060f0c13
commit
2282c56aaf
6 changed files with 274 additions and 45 deletions
|
@ -29,6 +29,7 @@ import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.ajax.SparqlUtils.AjaxControllerException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,8 +66,8 @@ public class SparqlQueryAjaxController extends VitroAjaxController {
|
||||||
String modelParam = getModelParam(vreq);
|
String modelParam = getModelParam(vreq);
|
||||||
Model model = locateModel(vreq, modelParam);
|
Model model = locateModel(vreq, modelParam);
|
||||||
String queryParam = locateQueryParam(vreq);
|
String queryParam = locateQueryParam(vreq);
|
||||||
Query query = createQuery(queryParam);
|
Query query = SparqlUtils.createQuery(queryParam);
|
||||||
executeQuery(response, query, model);
|
SparqlUtils.executeQuery(response, query, model);
|
||||||
return;
|
return;
|
||||||
} catch (AjaxControllerException e) {
|
} catch (AjaxControllerException e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
|
@ -121,40 +122,5 @@ public class SparqlQueryAjaxController extends VitroAjaxController {
|
||||||
+ PARAMETER_QUERY + "' parameter is required");
|
+ PARAMETER_QUERY + "' parameter is required");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Query createQuery(String queryParam) throws AjaxControllerException {
|
|
||||||
Query query = QueryFactory.create(queryParam, Syntax.syntaxARQ);
|
|
||||||
if (!query.isSelectType()) {
|
|
||||||
throw new AjaxControllerException(SC_NOT_FOUND,
|
|
||||||
"Only 'select' queries are allowed.");
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeQuery(HttpServletResponse response, Query query,
|
|
||||||
Model model) throws IOException {
|
|
||||||
Dataset dataset = DatasetFactory.create(model);
|
|
||||||
QueryExecution qe = QueryExecutionFactory.create(query, dataset);
|
|
||||||
try {
|
|
||||||
ResultSet results = qe.execSelect();
|
|
||||||
response.setContentType(RESPONSE_MIME_TYPE);
|
|
||||||
OutputStream out = response.getOutputStream();
|
|
||||||
ResultSetFormatter.outputAsJSON(out, results);
|
|
||||||
} finally {
|
|
||||||
qe.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class AjaxControllerException extends Exception {
|
|
||||||
private final int statusCode;
|
|
||||||
|
|
||||||
AjaxControllerException(int statusCode, String message) {
|
|
||||||
super(message);
|
|
||||||
this.statusCode = statusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStatusCode() {
|
|
||||||
return statusCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.ajax;
|
||||||
|
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
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 com.hp.hpl.jena.query.Dataset;
|
||||||
|
import com.hp.hpl.jena.query.DatasetFactory;
|
||||||
|
import com.hp.hpl.jena.query.Query;
|
||||||
|
import com.hp.hpl.jena.query.QueryExecution;
|
||||||
|
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
||||||
|
import com.hp.hpl.jena.query.QueryFactory;
|
||||||
|
import com.hp.hpl.jena.query.ResultSet;
|
||||||
|
import com.hp.hpl.jena.query.ResultSetFormatter;
|
||||||
|
import com.hp.hpl.jena.query.Syntax;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an AJAX request for a SPARQL query. On entry, the "query" parameter
|
||||||
|
* contains the query string.
|
||||||
|
*
|
||||||
|
* The result is delivered in JSON format.
|
||||||
|
*/
|
||||||
|
public class SparqlUtils {
|
||||||
|
private static final Log log = LogFactory
|
||||||
|
.getLog(SparqlQueryAjaxController.class);
|
||||||
|
|
||||||
|
public static final String RESPONSE_MIME_TYPE = "application/javascript";
|
||||||
|
|
||||||
|
public static final String PARAMETER_MODEL = "model";
|
||||||
|
public static final String OPTION_MODEL_FULL = "full";
|
||||||
|
public static final String OPTION_MODEL_USER_ACCOUNTS = "userAccounts";
|
||||||
|
|
||||||
|
|
||||||
|
public static Query createQuery(String queryParam) throws AjaxControllerException {
|
||||||
|
Query query = QueryFactory.create(queryParam, Syntax.syntaxARQ);
|
||||||
|
if (!query.isSelectType()) {
|
||||||
|
throw new AjaxControllerException(SC_NOT_FOUND,
|
||||||
|
"Only 'select' queries are allowed.");
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void executeQuery(HttpServletResponse response, Query query,
|
||||||
|
Model model) throws IOException {
|
||||||
|
Dataset dataset = DatasetFactory.create(model);
|
||||||
|
QueryExecution qe = QueryExecutionFactory.create(query, dataset);
|
||||||
|
try {
|
||||||
|
ResultSet results = qe.execSelect();
|
||||||
|
response.setContentType(RESPONSE_MIME_TYPE);
|
||||||
|
OutputStream out = response.getOutputStream();
|
||||||
|
ResultSetFormatter.outputAsJSON(out, results);
|
||||||
|
} finally {
|
||||||
|
qe.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class AjaxControllerException extends Exception {
|
||||||
|
private final int statusCode;
|
||||||
|
|
||||||
|
public AjaxControllerException(int statusCode, String message) {
|
||||||
|
super(message);
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -195,15 +195,15 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
|
||||||
|
|
||||||
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
|
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
|
||||||
Property prop = getPropertyByUri(predicateUri, wdf);
|
Property prop = getPropertyByUri(predicateUri, wdf);
|
||||||
|
//If we want to have data property custom form, we need to consider that as well
|
||||||
if(isDataProperty( prop , wdf )){
|
// if(isDataProperty( prop , wdf )){
|
||||||
editConfGeneratorName = DEFAULT_DATA_FORM;
|
// editConfGeneratorName = DEFAULT_DATA_FORM;
|
||||||
} else{
|
// } else{
|
||||||
String customForm = prop.getCustomEntryForm();
|
String customForm = prop.getCustomEntryForm();
|
||||||
if(customForm != null && !customForm.trim().isEmpty()) {
|
if(customForm != null && !customForm.trim().isEmpty()) {
|
||||||
editConfGeneratorName = customForm;
|
editConfGeneratorName = customForm;
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
|
|
||||||
log.debug("generator name is " + editConfGeneratorName);
|
log.debug("generator name is " + editConfGeneratorName);
|
||||||
return editConfGeneratorName;
|
return editConfGeneratorName;
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.search.controller;
|
||||||
|
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
|
import org.apache.solr.client.solrj.SolrServer;
|
||||||
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
|
import org.apache.solr.common.SolrDocument;
|
||||||
|
import org.apache.solr.common.SolrDocumentList;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.query.Dataset;
|
||||||
|
import com.hp.hpl.jena.query.DatasetFactory;
|
||||||
|
import com.hp.hpl.jena.query.Query;
|
||||||
|
import com.hp.hpl.jena.query.QueryExecution;
|
||||||
|
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
||||||
|
import com.hp.hpl.jena.query.QuerySolution;
|
||||||
|
import com.hp.hpl.jena.query.ResultSet;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Literal;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.ajax.SparqlUtils;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.ajax.SparqlUtils.AjaxControllerException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataAutocompleteController generates autocomplete content
|
||||||
|
* for data properties using sparql queries
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DataAutocompleteController extends VitroAjaxController {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final Log log = LogFactory.getLog(DataAutocompleteController.class);
|
||||||
|
|
||||||
|
private static final String PARAM_QUERY = "term";
|
||||||
|
//To get the data property
|
||||||
|
private static final String PARAM_PROPERTY = "property";
|
||||||
|
|
||||||
|
|
||||||
|
String NORESULT_MSG = "";
|
||||||
|
private static final int DEFAULT_MAX_HIT_COUNT = 1000;
|
||||||
|
|
||||||
|
public static final int MAX_QUERY_LENGTH = 500;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Actions requiredActions(VitroRequest vreq) {
|
||||||
|
//used to be basic vitro ajax permission but need to query full model
|
||||||
|
return SimplePermission.QUERY_FULL_MODEL.ACTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRequest(VitroRequest vreq, HttpServletResponse response)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
//This is the literal being searched for
|
||||||
|
String qtxt = vreq.getParameter(PARAM_QUERY);
|
||||||
|
String property = vreq.getParameter(PARAM_PROPERTY);
|
||||||
|
//Get sparql query for this property
|
||||||
|
String sparqlQuery = getSparqlQuery(qtxt, property);
|
||||||
|
//Forward this to SparqlQueryAjaxController as that already
|
||||||
|
//handles execution of query and will return json results
|
||||||
|
// String encodedQuery = URLEncoder.encode(sparqlQuery, "UTF-8");
|
||||||
|
// response.sendRedirect(vreq.getContextPath() + "/ajax/sparqlQuery?query=" + encodedQuery);
|
||||||
|
//RequestDispatcher dispatcher = vreq.getRequestDispatcher("/ajax/sparqlQuery?query=" + encodedQuery );
|
||||||
|
//dispatcher.forward(vreq, response);
|
||||||
|
|
||||||
|
//Get Model and execute query
|
||||||
|
Model model = getModel(vreq);
|
||||||
|
Query query = SparqlUtils.createQuery(sparqlQuery);
|
||||||
|
outputResults(response, query, model);
|
||||||
|
return;
|
||||||
|
} catch(AjaxControllerException ex) {
|
||||||
|
log.error(ex, ex);
|
||||||
|
response.sendError(ex.getStatusCode());
|
||||||
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
|
log.error(e, e);
|
||||||
|
//doSearchError(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void outputResults(HttpServletResponse response, Query query,
|
||||||
|
Model model) throws IOException{
|
||||||
|
Dataset dataset = DatasetFactory.create(model);
|
||||||
|
//Iterate through results and print out array of strings
|
||||||
|
List<String> outputResults = new ArrayList<String>();
|
||||||
|
QueryExecution qe = QueryExecutionFactory.create(query, dataset);
|
||||||
|
try {
|
||||||
|
ResultSet results = qe.execSelect();
|
||||||
|
while(results.hasNext()) {
|
||||||
|
QuerySolution qs = results.nextSolution();
|
||||||
|
Literal dataLiteral = qs.getLiteral("dataLiteral");
|
||||||
|
String dataValue = dataLiteral.getString();
|
||||||
|
outputResults.add(dataValue);
|
||||||
|
}
|
||||||
|
JSONArray jsonArray = new JSONArray(outputResults);
|
||||||
|
try {
|
||||||
|
response.getWriter().write(jsonArray.toString());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error(e, e);
|
||||||
|
doSearchError(response);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
qe.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Model getModel(VitroRequest vreq) throws AjaxControllerException{
|
||||||
|
Model model = vreq.getJenaOntModel();
|
||||||
|
|
||||||
|
if (model == null) {
|
||||||
|
throw new AjaxControllerException(SC_INTERNAL_SERVER_ERROR,
|
||||||
|
"Model '' not found.");
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSparqlQuery(String qtxt, String property) {
|
||||||
|
//"i" denotes case insensitive
|
||||||
|
//Searches for data literals whose string version begins with the text denoted
|
||||||
|
String query = "SELECT DISTINCT ?dataLiteral where {" +
|
||||||
|
"?s <" + property + "> ?dataLiteral . " +
|
||||||
|
"FILTER(regex(str(?dataLiteral), \"^" + qtxt + "\", \"i\")) } ORDER BY ?dataLiteral";
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void doSearchError(HttpServletResponse response) throws IOException {
|
||||||
|
// For now, we are not sending an error message back to the client because
|
||||||
|
// with the default autocomplete configuration it chokes.
|
||||||
|
doNoSearchResults(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doNoSearchResults(HttpServletResponse response) throws IOException {
|
||||||
|
response.getWriter().write("[]");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -883,7 +883,15 @@
|
||||||
<servlet-name>AutocompleteController</servlet-name>
|
<servlet-name>AutocompleteController</servlet-name>
|
||||||
<url-pattern>/populateselect</url-pattern>
|
<url-pattern>/populateselect</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>DataAutocompleteController</servlet-name>
|
||||||
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.DataAutocompleteController</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>DataAutocompleteController</servlet-name>
|
||||||
|
<url-pattern>/dataautocomplete</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>ReorderController</servlet-name>
|
<servlet-name>ReorderController</servlet-name>
|
||||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.ReorderController</servlet-class>
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.ReorderController</servlet-class>
|
||||||
|
|
|
@ -133,7 +133,7 @@ name will be used as the label. -->
|
||||||
|
|
||||||
<#macro propertyListItem property statement editable >
|
<#macro propertyListItem property statement editable >
|
||||||
<li role="listitem">
|
<li role="listitem">
|
||||||
<#nested>
|
<#nested>
|
||||||
<@editingLinks "${property.localName}" statement editable/>
|
<@editingLinks "${property.localName}" statement editable/>
|
||||||
</li>
|
</li>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
@ -142,6 +142,7 @@ name will be used as the label. -->
|
||||||
<#if editable>
|
<#if editable>
|
||||||
<@editLink propertyLocalName statement extraParams />
|
<@editLink propertyLocalName statement extraParams />
|
||||||
<@deleteLink propertyLocalName statement extraParams />
|
<@deleteLink propertyLocalName statement extraParams />
|
||||||
|
|
||||||
</#if>
|
</#if>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue