VIVO-752: display most specific type in picklists where the list contains indivduals of different classes.

This commit is contained in:
Tim Worrall 2014-05-30 11:12:53 -04:00
parent 1ec5d1dec7
commit 03c87f49a4
3 changed files with 98 additions and 16 deletions

View file

@ -10,15 +10,23 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
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.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.utils.fields.FieldUtils;
public class IndividualsViaObjectPropetyOptions implements FieldOptions {
@ -30,11 +38,13 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
private String predicateUri;
private List<VClass> rangeTypes;
private String objectUri;
private VitroRequest vreq;
private boolean hasSubclasses = true;
private String defaultOptionLabel;
public IndividualsViaObjectPropetyOptions(String subjectUri,
String predicateUri, List<VClass> rangeTypes, String objectUri) throws Exception {
String predicateUri, List<VClass> rangeTypes, String objectUri, VitroRequest vreq) throws Exception {
super();
if (subjectUri == null || subjectUri.equals("")) {
@ -48,6 +58,7 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
this.predicateUri = predicateUri;
this.rangeTypes = rangeTypes;
this.objectUri = objectUri;
this.vreq = vreq;
}
public IndividualsViaObjectPropetyOptions(String subjectUri,
@ -55,6 +66,11 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
this (subjectUri, predicateUri, null, objectUri);
}
public IndividualsViaObjectPropetyOptions(String subjectUri,
String predicateUri, List<VClass> rangeTypes, String objectUri) throws Exception {
this (subjectUri, predicateUri, rangeTypes, objectUri, null);
}
public IndividualsViaObjectPropetyOptions setDefaultOptionLabel(String label){
this.defaultOptionLabel = label;
return this;
@ -81,6 +97,11 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
if (!rangeTypes.isEmpty()) {
vclassesURIs = filterToSubclassesOfRange(vclassesURIs, rangeTypes, wDaoFact);
// is there only one range class and does it have any subclasses? If not, there's no
// reason to get the mostSpecificType of the individuals displayed in the select element
if ( vreq != null && rangeTypes.size() == 1 ) {
hasSubclasses = rangeHasSubclasses(rangeTypes.get(0), vreq);
}
}
if (vclassesURIs.size() == 0) {
@ -108,11 +129,15 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
for (Individual ind : individuals) {
String uri = ind.getURI();
if (uri != null) {
optionsMap.put(uri, ind.getName().trim());
String label = ind.getName().trim();
List<String> msTypes = ind.getMostSpecificTypeURIs();
if ( hasSubclasses && msTypes.size() > 0 ) {
label += " (" + getMsTypeLocalName(msTypes.get(0), wDaoFact) + ")";
}
optionsMap.put(uri, label);
++optionsCount;
}
}
return optionsMap;
}
@ -169,5 +194,25 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
return null;
}
private String getMsTypeLocalName(String theUri, WebappDaoFactory wDaoFact) {
VClassDao vcDao = wDaoFact.getVClassDao();
VClass vClass = vcDao.getVClassByURI(theUri);
String theType = ((vClass.getName() == null) ? "" : vClass.getName());
return theType;
}
private boolean rangeHasSubclasses(VClass uri, VitroRequest vreq) {
String askQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"ASK { ?something rdfs:subClassOf <" + uri.getURI() + "> }";
try {
return getRdfService(vreq).sparqlAskQuery(askQuery);
} catch (RDFServiceException e) {
throw new RuntimeException(e);
}
}
private RDFService getRdfService(HttpServletRequest req) {
return RDFServiceUtils.getRDFService(new VitroRequest(req));
}
}

View file

@ -169,7 +169,6 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
} else {
log.error("Subject individual was null for");
}
return types;
}
@ -455,7 +454,8 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
subjectUri,
predicateUri,
rangeTypes,
objectUri));
objectUri,
vreq ));
}else{
field.setOptions(null);
}
@ -617,7 +617,6 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
"<" + subject + "> <" + predicate + "> ?objectVar .} ";
return query;
}
}

View file

@ -22,13 +22,17 @@ import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchQuery;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResponse;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocument;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchResultDocumentList;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
/**
@ -47,7 +51,8 @@ public class AutocompleteController extends VitroAjaxController {
private static final String PARAM_RDFTYPE = "type";
private static final String PARAM_MULTIPLE_RDFTYPE = "multipleTypes";
private boolean hasMultipleTypes = false;
String NORESULT_MSG = "";
private static final int DEFAULT_MAX_HIT_COUNT = 1000;
@ -63,9 +68,22 @@ public class AutocompleteController extends VitroAjaxController {
throws IOException, ServletException {
try {
String qtxt = vreq.getParameter(PARAM_QUERY);
String typeParam = vreq.getParameter(PARAM_RDFTYPE);
if (typeParam != null) {
String[] parts = typeParam.split(",");
if ( parts.length > 1 ) {
hasMultipleTypes = true;
}
else if ( parts.length == 1 ) {
String askQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"ASK { ?something rdfs:subClassOf <" + typeParam.replace(",","") + "> }";
if ( getRdfService(vreq).sparqlAskQuery(askQuery) ) {
hasMultipleTypes = true;
}
}
}
SearchQuery query = getQuery(qtxt, vreq);
if (query == null ) {
log.debug("query for '" + qtxt +"' is null.");
@ -105,7 +123,7 @@ public class AutocompleteController extends VitroAjaxController {
String name = doc.getStringValue(VitroSearchTermNames.NAME_RAW);
String mst = doc.getStringValue(VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS);
SearchResult result = new SearchResult(name, uri, mst);
SearchResult result = new SearchResult(name, uri, mst, hasMultipleTypes, vreq);
results.add(result);
log.debug("results = " + results.toString());
} catch(Exception e){
@ -113,7 +131,9 @@ public class AutocompleteController extends VitroAjaxController {
"hits" + e.getMessage());
}
}
// now that we have the search result, reset this boolean
hasMultipleTypes = false;
Collections.sort(results);
JSONArray jsonArray = new JSONArray();
@ -147,6 +167,7 @@ public class AutocompleteController extends VitroAjaxController {
// Filter by type
String typeParam = vreq.getParameter(PARAM_RDFTYPE);
String multipleTypesParam = vreq.getParameter(PARAM_MULTIPLE_RDFTYPE);
if (typeParam != null) {
addFilterQuery(query, typeParam, multipleTypesParam);
}
@ -274,17 +295,27 @@ public class AutocompleteController extends VitroAjaxController {
response.getWriter().write("[]");
}
private RDFService getRdfService(HttpServletRequest req) {
return RDFServiceUtils.getRDFService(new VitroRequest(req));
}
public class SearchResult implements Comparable<Object> {
private String label;
private String uri;
private String msType;
private boolean hasMultipleTypes;
SearchResult(String label, String uri, String msType) {
this.label = label;
SearchResult(String label, String uri, String msType, boolean hasMultipleTypes, VitroRequest vreq) {
if ( hasMultipleTypes ) {
this.label = label + " (" + getMsTypeLocalName(msType, vreq) + ")";
}
else {
this.label = label;
}
this.uri = uri;
this.msType = msType;
}
public String getLabel() {
return label;
}
@ -305,6 +336,13 @@ public class AutocompleteController extends VitroAjaxController {
return msType;
}
public String getMsTypeLocalName(String theUri, VitroRequest vreq) {
VClassDao vcDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getVClassDao();
VClass vClass = vcDao.getVClassByURI(theUri);
String theType = ((vClass.getName() == null) ? "" : vClass.getName());
return theType;
}
public String getJsonMsType() {
return JSONObject.quote(msType);
}