diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java index 7a326c18e..c773549f8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java @@ -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.requestedAction.Actions; 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; /** @@ -65,8 +66,8 @@ public class SparqlQueryAjaxController extends VitroAjaxController { String modelParam = getModelParam(vreq); Model model = locateModel(vreq, modelParam); String queryParam = locateQueryParam(vreq); - Query query = createQuery(queryParam); - executeQuery(response, query, model); + Query query = SparqlUtils.createQuery(queryParam); + SparqlUtils.executeQuery(response, query, model); return; } catch (AjaxControllerException e) { log.error(e.getMessage()); @@ -121,40 +122,5 @@ public class SparqlQueryAjaxController extends VitroAjaxController { + 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; - } - } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlUtils.java new file mode 100644 index 000000000..41f1da870 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlUtils.java @@ -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; + } + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java index 3172e8bdd..54947bb17 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java @@ -195,15 +195,15 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { WebappDaoFactory wdf = vreq.getWebappDaoFactory(); Property prop = getPropertyByUri(predicateUri, wdf); - - if(isDataProperty( prop , wdf )){ - editConfGeneratorName = DEFAULT_DATA_FORM; - } else{ + //If we want to have data property custom form, we need to consider that as well + // if(isDataProperty( prop , wdf )){ + // editConfGeneratorName = DEFAULT_DATA_FORM; + // } else{ String customForm = prop.getCustomEntryForm(); if(customForm != null && !customForm.trim().isEmpty()) { editConfGeneratorName = customForm; } - } + // } log.debug("generator name is " + editConfGeneratorName); return editConfGeneratorName; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/DataAutocompleteController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/DataAutocompleteController.java new file mode 100644 index 000000000..b4c1738a3 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/DataAutocompleteController.java @@ -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 outputResults = new ArrayList(); + 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("[]"); + } + +} diff --git a/webapp/web/WEB-INF/web.xml b/webapp/web/WEB-INF/web.xml index dad98b02f..b52417ea9 100644 --- a/webapp/web/WEB-INF/web.xml +++ b/webapp/web/WEB-INF/web.xml @@ -883,7 +883,15 @@ AutocompleteController /populateselect - + + + DataAutocompleteController + edu.cornell.mannlib.vitro.webapp.search.controller.DataAutocompleteController + + + DataAutocompleteController + /dataautocomplete + ReorderController edu.cornell.mannlib.vitro.webapp.controller.edit.ReorderController diff --git a/webapp/web/templates/freemarker/lib/lib-properties.ftl b/webapp/web/templates/freemarker/lib/lib-properties.ftl index 90ad6bea2..d5f645034 100644 --- a/webapp/web/templates/freemarker/lib/lib-properties.ftl +++ b/webapp/web/templates/freemarker/lib/lib-properties.ftl @@ -133,7 +133,7 @@ name will be used as the label. --> <#macro propertyListItem property statement editable >
  • - <#nested> + <#nested> <@editingLinks "${property.localName}" statement editable/>
  • @@ -142,6 +142,7 @@ name will be used as the label. --> <#if editable> <@editLink propertyLocalName statement extraParams /> <@deleteLink propertyLocalName statement extraParams /> +