From 542d1c30effaf83705bd9b60e9e5a480accc61a5 Mon Sep 17 00:00:00 2001 From: michel-heon Date: Fri, 28 Oct 2022 15:53:25 +0000 Subject: [PATCH 1/3] Replacement of language comparisons using '=' by the 'langMatches' function --- .../FakeApplicationOntologyService.java | 919 +++++++++--------- 1 file changed, 461 insertions(+), 458 deletions(-) diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java index 770aab1818..1f6b7aff6a 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java @@ -52,463 +52,466 @@ * TODO Get rid of this when the Application Ontology is implemented. */ public class FakeApplicationOntologyService { - private static final Log log = LogFactory - .getLog(FakeApplicationOntologyService.class); - - public static final String FILE_OF_SHORT_VIEW_INFO = "/WEB-INF/resources/shortview_config.n3"; - - private static final String NS = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#"; - private static final String HAS_TEMPLATE = NS + "hasTemplate"; - private static final String CUSTOM_VIEW = NS + "customViewForIndividual"; - private static final String APPLIES_TO = NS + "appliesToContext"; - private static final String HAS_DATA_GETTER = NS + "hasDataGetter"; - private static final String HAS_VIEW = NS + "hasCustomView"; - private static final String RDF_TYPE = VitroVocabulary.RDF_TYPE; - - private final OntModel viewModel; - private final Map> classUriToViewSpecs; - - /** - * Load the model from the config file, and inspect it for Views and - * mappings. - * - * Keep the model - we'll need it when its time to create the DataGetters - * (on each request). - */ - public FakeApplicationOntologyService(ServletContext ctx) - throws ShortViewConfigException { - this.viewModel = createModelFromFile(ctx); - - Map viewSpecsByUri = createViewSpecs(); - this.classUriToViewSpecs = createClassMappings(viewSpecsByUri); - - if (log.isDebugEnabled()) { - log.debug("Mapping: " + classUriToViewSpecs); - } - } - - /** - * If we fail to parse the config file, use this constructor instead, to - * simulate an empty config file. - */ - public FakeApplicationOntologyService() { - this.viewModel = ModelFactory - .createOntologyModel(OntModelSpec.OWL_DL_MEM); - this.classUriToViewSpecs = new HashMap>(); - - log.debug("Created empty FakeApplicationOntologyService."); - } - - /** - * Load the short view config file into an OntModel. - */ - private OntModel createModelFromFile(ServletContext ctx) - throws ShortViewConfigException { - InputStream stream = ctx.getResourceAsStream(FILE_OF_SHORT_VIEW_INFO); - if (stream == null) { - throw new ShortViewConfigException("The short view config file " - + "doesn't exist in the servlet context: '" - + FILE_OF_SHORT_VIEW_INFO + "'"); - } - - OntModel m = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM); - try { - m.read(stream, null, "N3"); - } catch (Exception e) { - throw new ShortViewConfigException( - "Parsing error in the short view config file.", e); - } finally { - try { - stream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - log.debug("Loaded " + m.size() + " statements"); - return m; - } - - /** - * Find all of the views. - */ - private Map createViewSpecs() - throws ShortViewConfigException { - Property rdfType = viewModel.getProperty(RDF_TYPE); - Property appliesTo = viewModel.getProperty(APPLIES_TO); - Property dataGetter = viewModel.getProperty(HAS_DATA_GETTER); - Property template = viewModel.getProperty(HAS_TEMPLATE); - Resource customView = viewModel.getResource(CUSTOM_VIEW); - - ResIterator views = viewModel.listResourcesWithProperty(rdfType, - customView); - try { - Map map = new HashMap(); - while (views.hasNext()) { - Resource view = views.next(); - List contextNames = getDataPropertyValues(view, - appliesTo, "context"); - List contexts = contextsFromNames(view, - contextNames); - List dataGetterUris = getObjectPropertyValues(view, - dataGetter, "data getter"); - String tn = getDataProperty(view, template); - map.put(view.getURI(), new ViewSpec(view.getURI(), contexts, - dataGetterUris, tn)); - } - return map; - } finally { - views.close(); - } - } - - /** - * Got a list of context names. Make sure that each one actually represents - * a known context. - */ - private List contextsFromNames(Resource view, - List contextNames) throws ShortViewConfigException { - List list = new ArrayList(); - for (String name : contextNames) { - ShortViewContext context = ShortViewContext.fromString(name); - if (context == null) { - throw new ShortViewConfigException("Unrecognized context '" - + name + "' for view '" + view.getURI() + "'"); - } - list.add(context); - } - return list; - } - - /** - * Create a map of classes to views. - */ - private Map> createClassMappings( - Map viewSpecsByUri) - throws ShortViewConfigException { - Property hasView = viewModel.getProperty(HAS_VIEW); - - StmtIterator stmts = viewModel.listStatements(null, hasView, - (RDFNode) null); - try { - Map> map = new HashMap>(); - while (stmts.hasNext()) { - Statement s = stmts.next(); - - String classUri = s.getSubject().getURI(); - - RDFNode node = s.getObject(); - if (!node.isResource()) { - throw new ShortViewConfigException("The hasCustomView" - + " property for '" + classUri - + "' must be a resource."); - } - String viewUri = node.asResource().getURI(); - - ViewSpec view = viewSpecsByUri.get(viewUri); - if (view == null) { - throw new ShortViewConfigException("On '" + classUri - + "', the view '" + viewUri + "' does not exist."); - } - - if (!map.containsKey(classUri)) { - map.put(classUri, new ArrayList()); - } - map.get(classUri).add(view); - } - return map; - } finally { - stmts.close(); - } - } - - private String getDataProperty(Resource subject, Property predicate) - throws ShortViewConfigException { - Statement s = viewModel.getProperty(subject, predicate); - if (s == null) { - throw new ShortViewConfigException("The required property '" - + predicate.getURI() + "' is not present for '" - + subject.getURI() + "'"); - } - RDFNode node = s.getObject(); - if (!node.isLiteral()) - throw new ShortViewConfigException("The value of '" - + predicate.getURI() + "' for '" + subject.getURI() - + "' must be a literal."); - return node.asLiteral().getString(); - } - - private List getDataPropertyValues(Resource subject, - Property predicate, String label) throws ShortViewConfigException { - StmtIterator stmts = viewModel.listStatements(subject, predicate, - (RDFNode) null); - try { - List list = new ArrayList(); - while (stmts.hasNext()) { - Statement stmt = stmts.next(); - RDFNode node = stmt.getObject(); - if (!node.isLiteral()) { - throw new ShortViewConfigException("The " + label - + " property for '" + subject.getURI() - + "' must be a literal."); - } - list.add(node.asLiteral().getString()); - } - return list; - } finally { - stmts.close(); - } - } - - private List getObjectPropertyValues(Resource subject, - Property predicate, String label) throws ShortViewConfigException { - StmtIterator stmts = viewModel.listStatements(subject, predicate, - (RDFNode) null); - try { - List list = new ArrayList(); - while (stmts.hasNext()) { - Statement stmt = stmts.next(); - RDFNode node = stmt.getObject(); - if (!node.isResource()) { - throw new ShortViewConfigException("The " + label - + " property for '" + subject.getURI() - + "' must be a resource."); - } - list.add(node.asResource().getURI()); - } - return list; - } finally { - stmts.close(); - } - } - - /** - * Return the template name and DataGetter instances associated with this - * class and this short view context. If none, return null. - */ - public TemplateAndDataGetters getShortViewProperties(VitroRequest vreq, - Individual individual, String classUri, String contextName) { - /* - * If we have a mapping for this class that applies to this context, - * construct the DataGetter instances and return them with the template. - */ - if (classUriToViewSpecs.containsKey(classUri)) { - for (ViewSpec view : classUriToViewSpecs.get(classUri)) { - for (ShortViewContext context : view.getContexts()) { - if (context.name().equalsIgnoreCase(contextName)) { - List dgList = new ArrayList(); - for (String dgUri : view.getDataGetterUris()) { - dgList.add(new SparqlQueryDataGetter(vreq, - viewModel, dgUri)); - } - return new TemplateAndDataGetters( - view.getTemplateName(), - dgList.toArray(new DataGetter[0])); - } - } - } - } - - /* - * Otherwise, check for this hard-coded kluge. Any class in the People - * class group gets a special view with preferred title. - */ - if ((BROWSE.name().equals(contextName)) - && (isClassInPeopleClassGroup(vreq.getWebappDaoFactory(), - classUri))) { - return new TemplateAndDataGetters("view-browse-people.ftl", - new FakeVivoPeopleDataGetter(vreq, individual.getURI())); - } - - /* - * Otherwise, no custom view. - */ - return null; - } - - private boolean isClassInPeopleClassGroup(WebappDaoFactory wadf, - String classUri) { - if (wadf == null) { - log.debug("isClassInPeopleClassGroup: WebappDaoFactory is null."); - return false; - } - - VClassDao vcDao = wadf.getVClassDao(); - if (vcDao == null) { - log.debug("isClassInPeopleClassGroup: VClassDao is null."); - return false; - } - - VClass vclass = vcDao.getVClassByURI(classUri); - if (vclass == null) { - log.debug("isClassInPeopleClassGroup: VClass is null."); - return false; - } - - String vclassGroupUri = vclass.getGroupURI(); - if (vclassGroupUri == null) { - log.debug("isClassInPeopleClassGroup: vclassGroupUri is null."); - return false; - } - - boolean isPeople = PEOPLE_CLASSGROUP_URI.equals(vclassGroupUri); - log.debug("isClassInPeopleClassGroup: isPeople = " + isPeople); - return isPeople; - } - - // ---------------------------------------------------------------------- - // Helper classes - // ---------------------------------------------------------------------- - - /** The info associated with a short view. */ - public static class TemplateAndDataGetters { - private final String templateName; - private final Set dataGetters; - - public TemplateAndDataGetters(String templateName, - DataGetter... dataGetters) { - this.templateName = templateName; - this.dataGetters = new HashSet( - Arrays.asList(dataGetters)); - } - - public String getTemplateName() { - return templateName; - } - - public Set getDataGetters() { - return dataGetters; - } - - @Override - public String toString() { - return "[template=" + templateName + ", dataGetters=" + dataGetters - + "]"; - } - - } - - /** The view specifications that we read from the config file. */ - private class ViewSpec { - private final String uri; - private final List contexts; - private final List dataGetterUris; - private final String templateName; - - public ViewSpec(String uri, List contexts, - List dataGetterUris, String templateName) { - this.uri = uri; - this.contexts = contexts; - this.dataGetterUris = dataGetterUris; - this.templateName = templateName; - } - - public List getContexts() { - return contexts; - } - - public List getDataGetterUris() { - return dataGetterUris; - } - - public String getTemplateName() { - return templateName; - } - - @Override - public String toString() { - return "ViewSpec[uri='" + uri + "', contexts=" + contexts - + ", dataGetterUris=" + dataGetterUris + ", templateName='" - + templateName + "']"; - } - - } - - /** A custom exception that says something was wrong with the config file. */ - public class ShortViewConfigException extends Exception { - public ShortViewConfigException(String message) { - super(message); - } - - public ShortViewConfigException(String message, Throwable cause) { - super(message, cause); - } - } - - private static final String PEOPLE_CLASSGROUP_URI = "http://vivoweb.org/ontology#vitroClassGrouppeople"; - - /** - * A special data getter to support the kluge case of browsing an individual - * that belongs to the People class group. - * - * A SPARQL query data getter that initializes itself from its own private - * "display model". The query finds a preferred title for the individual. - */ - private static class FakeVivoPeopleDataGetter extends SparqlQueryDataGetter { - // private static String QUERY_STRING = "" - // + "PREFIX obo: \n" - // + "PREFIX vcard: \n" - // + "SELECT ?pt \n" + "WHERE { \n" - // + " ?uri obo:ARG_2000028 ?vIndividual . \n" - // + " ?vIndividual vcard:hasTitle ?vTitle . \n" - // + " ?vTitle vcard:title ?pt . \n" + "} LIMIT 1"; - - /* - * UQAM-Optimization New query including Linguistic context - */ - private static String QUERY_STRING_LANG = "" - + "PREFIX obo: \n" - + "PREFIX vcard: \n" - + "SELECT ?pt \n" + "WHERE { \n" - + " ?uri obo:ARG_2000028 ?vIndividual . \n" - + " ?vIndividual vcard:hasTitle ?vTitle . \n" - + " ?vTitle vcard:title ?pt . \n" - + " FILTER (lang(?pt) = '?langCtx' ) \n" - + " } LIMIT 1"; - private static final String FAKE_VIVO_PEOPLE_DATA_GETTER_URI = "http://FakeVivoPeopleDataGetter"; - - private static OntModel fakeDisplayModel = initializeFakeDisplayModel(); - - private static OntModel initializeFakeDisplayModel() { - OntModel m = ModelFactory - .createOntologyModel(OntModelSpec.OWL_DL_MEM); - - Resource dataGetter = m - .getResource(FAKE_VIVO_PEOPLE_DATA_GETTER_URI); - Property queryProperty = m.getProperty(DisplayVocabulary.QUERY); - Property saveToVarProperty = m - .getProperty(DisplayVocabulary.SAVE_TO_VAR); - - m.add(dataGetter, queryProperty, QUERY_STRING_LANG); //UQAM-Optimization Using query with linguistic context - m.add(dataGetter, saveToVarProperty, "extra"); - return m; - } - - private String individualUri; - private VitroRequest vreq; - private ServletContext ctx; - private String langCtx = "en-US"; - - public FakeVivoPeopleDataGetter(VitroRequest vreq, String individualUri) { - super(vreq, initializeFakeDisplayModel(), "http://FakeVivoPeopleDataGetter"); - this.individualUri = individualUri; - this.vreq = vreq; - this.ctx = vreq.getSession().getServletContext(); - this.langCtx = vreq.getLocale().getLanguage(); // UQAM-Optimization add the linguistic context - if (!vreq.getLocale().getCountry().isEmpty()) { - this.langCtx += "-" + vreq.getLocale().getCountry(); - } - } - - @Override - public Map getData(Map pageData) { - Map parms = new HashMap<>(); - parms.put("uri", individualUri); - parms.put("langCtx", langCtx); //UQAM-Optimization add the linguistic context - - return super.getData(parms); - } - - } + private static final Log log = LogFactory + .getLog(FakeApplicationOntologyService.class); + + public static final String FILE_OF_SHORT_VIEW_INFO = "/WEB-INF/resources/shortview_config.n3"; + + private static final String NS = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#"; + private static final String HAS_TEMPLATE = NS + "hasTemplate"; + private static final String CUSTOM_VIEW = NS + "customViewForIndividual"; + private static final String APPLIES_TO = NS + "appliesToContext"; + private static final String HAS_DATA_GETTER = NS + "hasDataGetter"; + private static final String HAS_VIEW = NS + "hasCustomView"; + private static final String RDF_TYPE = VitroVocabulary.RDF_TYPE; + + private final OntModel viewModel; + private final Map> classUriToViewSpecs; + + /** + * Load the model from the config file, and inspect it for Views and + * mappings. + * + * Keep the model - we'll need it when its time to create the DataGetters + * (on each request). + */ + public FakeApplicationOntologyService(ServletContext ctx) + throws ShortViewConfigException { + this.viewModel = createModelFromFile(ctx); + + Map viewSpecsByUri = createViewSpecs(); + this.classUriToViewSpecs = createClassMappings(viewSpecsByUri); + + if (log.isDebugEnabled()) { + log.debug("Mapping: " + classUriToViewSpecs); + } + } + + /** + * If we fail to parse the config file, use this constructor instead, to + * simulate an empty config file. + */ + public FakeApplicationOntologyService() { + this.viewModel = ModelFactory + .createOntologyModel(OntModelSpec.OWL_DL_MEM); + this.classUriToViewSpecs = new HashMap>(); + + log.debug("Created empty FakeApplicationOntologyService."); + } + + /** + * Load the short view config file into an OntModel. + */ + private OntModel createModelFromFile(ServletContext ctx) + throws ShortViewConfigException { + InputStream stream = ctx.getResourceAsStream(FILE_OF_SHORT_VIEW_INFO); + if (stream == null) { + throw new ShortViewConfigException("The short view config file " + + "doesn't exist in the servlet context: '" + + FILE_OF_SHORT_VIEW_INFO + "'"); + } + + OntModel m = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM); + try { + m.read(stream, null, "N3"); + } catch (Exception e) { + throw new ShortViewConfigException( + "Parsing error in the short view config file.", e); + } finally { + try { + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + log.debug("Loaded " + m.size() + " statements"); + return m; + } + + /** + * Find all of the views. + */ + private Map createViewSpecs() + throws ShortViewConfigException { + Property rdfType = viewModel.getProperty(RDF_TYPE); + Property appliesTo = viewModel.getProperty(APPLIES_TO); + Property dataGetter = viewModel.getProperty(HAS_DATA_GETTER); + Property template = viewModel.getProperty(HAS_TEMPLATE); + Resource customView = viewModel.getResource(CUSTOM_VIEW); + + ResIterator views = viewModel.listResourcesWithProperty(rdfType, + customView); + try { + Map map = new HashMap(); + while (views.hasNext()) { + Resource view = views.next(); + List contextNames = getDataPropertyValues(view, + appliesTo, "context"); + List contexts = contextsFromNames(view, + contextNames); + List dataGetterUris = getObjectPropertyValues(view, + dataGetter, "data getter"); + String tn = getDataProperty(view, template); + map.put(view.getURI(), new ViewSpec(view.getURI(), contexts, + dataGetterUris, tn)); + } + return map; + } finally { + views.close(); + } + } + + /** + * Got a list of context names. Make sure that each one actually represents + * a known context. + */ + private List contextsFromNames(Resource view, + List contextNames) throws ShortViewConfigException { + List list = new ArrayList(); + for (String name : contextNames) { + ShortViewContext context = ShortViewContext.fromString(name); + if (context == null) { + throw new ShortViewConfigException("Unrecognized context '" + + name + "' for view '" + view.getURI() + "'"); + } + list.add(context); + } + return list; + } + + /** + * Create a map of classes to views. + */ + private Map> createClassMappings( + Map viewSpecsByUri) + throws ShortViewConfigException { + Property hasView = viewModel.getProperty(HAS_VIEW); + + StmtIterator stmts = viewModel.listStatements(null, hasView, + (RDFNode) null); + try { + Map> map = new HashMap>(); + while (stmts.hasNext()) { + Statement s = stmts.next(); + + String classUri = s.getSubject().getURI(); + + RDFNode node = s.getObject(); + if (!node.isResource()) { + throw new ShortViewConfigException("The hasCustomView" + + " property for '" + classUri + + "' must be a resource."); + } + String viewUri = node.asResource().getURI(); + + ViewSpec view = viewSpecsByUri.get(viewUri); + if (view == null) { + throw new ShortViewConfigException("On '" + classUri + + "', the view '" + viewUri + "' does not exist."); + } + + if (!map.containsKey(classUri)) { + map.put(classUri, new ArrayList()); + } + map.get(classUri).add(view); + } + return map; + } finally { + stmts.close(); + } + } + + private String getDataProperty(Resource subject, Property predicate) + throws ShortViewConfigException { + Statement s = viewModel.getProperty(subject, predicate); + if (s == null) { + throw new ShortViewConfigException("The required property '" + + predicate.getURI() + "' is not present for '" + + subject.getURI() + "'"); + } + RDFNode node = s.getObject(); + if (!node.isLiteral()) + throw new ShortViewConfigException("The value of '" + + predicate.getURI() + "' for '" + subject.getURI() + + "' must be a literal."); + return node.asLiteral().getString(); + } + + private List getDataPropertyValues(Resource subject, + Property predicate, String label) throws ShortViewConfigException { + StmtIterator stmts = viewModel.listStatements(subject, predicate, + (RDFNode) null); + try { + List list = new ArrayList(); + while (stmts.hasNext()) { + Statement stmt = stmts.next(); + RDFNode node = stmt.getObject(); + if (!node.isLiteral()) { + throw new ShortViewConfigException("The " + label + + " property for '" + subject.getURI() + + "' must be a literal."); + } + list.add(node.asLiteral().getString()); + } + return list; + } finally { + stmts.close(); + } + } + + private List getObjectPropertyValues(Resource subject, + Property predicate, String label) throws ShortViewConfigException { + StmtIterator stmts = viewModel.listStatements(subject, predicate, + (RDFNode) null); + try { + List list = new ArrayList(); + while (stmts.hasNext()) { + Statement stmt = stmts.next(); + RDFNode node = stmt.getObject(); + if (!node.isResource()) { + throw new ShortViewConfigException("The " + label + + " property for '" + subject.getURI() + + "' must be a resource."); + } + list.add(node.asResource().getURI()); + } + return list; + } finally { + stmts.close(); + } + } + + /** + * Return the template name and DataGetter instances associated with this + * class and this short view context. If none, return null. + */ + public TemplateAndDataGetters getShortViewProperties(VitroRequest vreq, + Individual individual, String classUri, String contextName) { + /* + * If we have a mapping for this class that applies to this context, + * construct the DataGetter instances and return them with the template. + */ + if (classUriToViewSpecs.containsKey(classUri)) { + for (ViewSpec view : classUriToViewSpecs.get(classUri)) { + for (ShortViewContext context : view.getContexts()) { + if (context.name().equalsIgnoreCase(contextName)) { + List dgList = new ArrayList(); + for (String dgUri : view.getDataGetterUris()) { + dgList.add(new SparqlQueryDataGetter(vreq, + viewModel, dgUri)); + } + return new TemplateAndDataGetters( + view.getTemplateName(), + dgList.toArray(new DataGetter[0])); + } + } + } + } + + /* + * Otherwise, check for this hard-coded kluge. Any class in the People + * class group gets a special view with preferred title. + */ + if ((BROWSE.name().equals(contextName)) + && (isClassInPeopleClassGroup(vreq.getWebappDaoFactory(), + classUri))) { + return new TemplateAndDataGetters("view-browse-people.ftl", + new FakeVivoPeopleDataGetter(vreq, individual.getURI())); + } + + /* + * Otherwise, no custom view. + */ + return null; + } + + private boolean isClassInPeopleClassGroup(WebappDaoFactory wadf, + String classUri) { + if (wadf == null) { + log.debug("isClassInPeopleClassGroup: WebappDaoFactory is null."); + return false; + } + + VClassDao vcDao = wadf.getVClassDao(); + if (vcDao == null) { + log.debug("isClassInPeopleClassGroup: VClassDao is null."); + return false; + } + + VClass vclass = vcDao.getVClassByURI(classUri); + if (vclass == null) { + log.debug("isClassInPeopleClassGroup: VClass is null."); + return false; + } + + String vclassGroupUri = vclass.getGroupURI(); + if (vclassGroupUri == null) { + log.debug("isClassInPeopleClassGroup: vclassGroupUri is null."); + return false; + } + + boolean isPeople = PEOPLE_CLASSGROUP_URI.equals(vclassGroupUri); + log.debug("isClassInPeopleClassGroup: isPeople = " + isPeople); + return isPeople; + } + + // ---------------------------------------------------------------------- + // Helper classes + // ---------------------------------------------------------------------- + + /** The info associated with a short view. */ + public static class TemplateAndDataGetters { + private final String templateName; + private final Set dataGetters; + + public TemplateAndDataGetters(String templateName, + DataGetter... dataGetters) { + this.templateName = templateName; + this.dataGetters = new HashSet( + Arrays.asList(dataGetters)); + } + + public String getTemplateName() { + return templateName; + } + + public Set getDataGetters() { + return dataGetters; + } + + @Override + public String toString() { + return "[template=" + templateName + ", dataGetters=" + dataGetters + + "]"; + } + + } + + /** The view specifications that we read from the config file. */ + private class ViewSpec { + private final String uri; + private final List contexts; + private final List dataGetterUris; + private final String templateName; + + public ViewSpec(String uri, List contexts, + List dataGetterUris, String templateName) { + this.uri = uri; + this.contexts = contexts; + this.dataGetterUris = dataGetterUris; + this.templateName = templateName; + } + + public List getContexts() { + return contexts; + } + + public List getDataGetterUris() { + return dataGetterUris; + } + + public String getTemplateName() { + return templateName; + } + + @Override + public String toString() { + return "ViewSpec[uri='" + uri + "', contexts=" + contexts + + ", dataGetterUris=" + dataGetterUris + ", templateName='" + + templateName + "']"; + } + + } + + /** A custom exception that says something was wrong with the config file. */ + public class ShortViewConfigException extends Exception { + public ShortViewConfigException(String message) { + super(message); + } + + public ShortViewConfigException(String message, Throwable cause) { + super(message, cause); + } + } + + private static final String PEOPLE_CLASSGROUP_URI = "http://vivoweb.org/ontology#vitroClassGrouppeople"; + + /** + * A special data getter to support the kluge case of browsing an individual + * that belongs to the People class group. + * + * A SPARQL query data getter that initializes itself from its own private + * "display model". The query finds a preferred title for the individual. + */ + private static class FakeVivoPeopleDataGetter extends SparqlQueryDataGetter { + // private static String QUERY_STRING = "" + // + "PREFIX obo: \n" + // + "PREFIX vcard: \n" + // + "SELECT ?pt \n" + "WHERE { \n" + // + " ?uri obo:ARG_2000028 ?vIndividual . \n" + // + " ?vIndividual vcard:hasTitle ?vTitle . \n" + // + " ?vTitle vcard:title ?pt . \n" + "} LIMIT 1"; + + /* + * UQAM-Optimization New query including Linguistic context + * and UQAM - In the filter, Case-insensitive language processing + */ + private static String QUERY_STRING_LANG(String lang) { + return "\n" + + "PREFIX obo: \n" + + "PREFIX vcard: \n" + + "SELECT ?pt \n" + "WHERE { \n" + + " ?uri obo:ARG_2000028 ?vIndividual . \n" + + " ?vIndividual vcard:hasTitle ?vTitle . \n" + + " ?vTitle vcard:title ?pt . \n" + // + " FILTER (lang(?pt) = '?langCtx' ) \n" old and buggy + + " FILTER (langMatches(lang(?pt), '" + lang+"' ) ) \n" + + " } LIMIT 1"; + } + private static final String FAKE_VIVO_PEOPLE_DATA_GETTER_URI = "http://FakeVivoPeopleDataGetter"; + + private static OntModel fakeDisplayModel = initializeFakeDisplayModel(); + + private static OntModel initializeFakeDisplayModel() { + OntModel m = ModelFactory + .createOntologyModel(OntModelSpec.OWL_DL_MEM); + + Resource dataGetter = m + .getResource(FAKE_VIVO_PEOPLE_DATA_GETTER_URI); + Property queryProperty = m.getProperty(DisplayVocabulary.QUERY); + Property saveToVarProperty = m + .getProperty(DisplayVocabulary.SAVE_TO_VAR); + + m.add(dataGetter, queryProperty, QUERY_STRING_LANG("en-US")); //UQAM-Optimization Using query with linguistic context + m.add(dataGetter, saveToVarProperty, "extra"); + return m; + } + + private String individualUri; + private VitroRequest vreq; + private ServletContext ctx; + private String langCtx = "en-US"; + + public FakeVivoPeopleDataGetter(VitroRequest vreq, String individualUri) { + super(vreq, initializeFakeDisplayModel(), "http://FakeVivoPeopleDataGetter"); + this.individualUri = individualUri; + this.vreq = vreq; + this.ctx = vreq.getSession().getServletContext(); + this.langCtx = vreq.getLocale().getLanguage(); // UQAM-Optimization add the linguistic context + if (!vreq.getLocale().getCountry().isEmpty()) { + this.langCtx += "-" + vreq.getLocale().getCountry(); + } + } + + @Override + public Map getData(Map pageData) { + Map parms = new HashMap<>(); + parms.put("uri", individualUri); + parms.put("langCtx", langCtx); //UQAM-Optimization add the linguistic context + return super.getData(parms); + } + + } } From 108fdbf66b7414c7e46a5e6f28d464d4e123be56 Mon Sep 17 00:00:00 2001 From: William Welling Date: Thu, 9 Feb 2023 11:15:15 -0600 Subject: [PATCH 2/3] Undo whitespace changes --- .../FakeApplicationOntologyService.java | 922 +++++++++--------- 1 file changed, 461 insertions(+), 461 deletions(-) diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java index 1f6b7aff6a..96ee072559 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java @@ -52,466 +52,466 @@ * TODO Get rid of this when the Application Ontology is implemented. */ public class FakeApplicationOntologyService { - private static final Log log = LogFactory - .getLog(FakeApplicationOntologyService.class); - - public static final String FILE_OF_SHORT_VIEW_INFO = "/WEB-INF/resources/shortview_config.n3"; - - private static final String NS = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#"; - private static final String HAS_TEMPLATE = NS + "hasTemplate"; - private static final String CUSTOM_VIEW = NS + "customViewForIndividual"; - private static final String APPLIES_TO = NS + "appliesToContext"; - private static final String HAS_DATA_GETTER = NS + "hasDataGetter"; - private static final String HAS_VIEW = NS + "hasCustomView"; - private static final String RDF_TYPE = VitroVocabulary.RDF_TYPE; - - private final OntModel viewModel; - private final Map> classUriToViewSpecs; - - /** - * Load the model from the config file, and inspect it for Views and - * mappings. - * - * Keep the model - we'll need it when its time to create the DataGetters - * (on each request). - */ - public FakeApplicationOntologyService(ServletContext ctx) - throws ShortViewConfigException { - this.viewModel = createModelFromFile(ctx); - - Map viewSpecsByUri = createViewSpecs(); - this.classUriToViewSpecs = createClassMappings(viewSpecsByUri); - - if (log.isDebugEnabled()) { - log.debug("Mapping: " + classUriToViewSpecs); - } - } - - /** - * If we fail to parse the config file, use this constructor instead, to - * simulate an empty config file. - */ - public FakeApplicationOntologyService() { - this.viewModel = ModelFactory - .createOntologyModel(OntModelSpec.OWL_DL_MEM); - this.classUriToViewSpecs = new HashMap>(); - - log.debug("Created empty FakeApplicationOntologyService."); - } - - /** - * Load the short view config file into an OntModel. - */ - private OntModel createModelFromFile(ServletContext ctx) - throws ShortViewConfigException { - InputStream stream = ctx.getResourceAsStream(FILE_OF_SHORT_VIEW_INFO); - if (stream == null) { - throw new ShortViewConfigException("The short view config file " - + "doesn't exist in the servlet context: '" - + FILE_OF_SHORT_VIEW_INFO + "'"); - } - - OntModel m = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM); - try { - m.read(stream, null, "N3"); - } catch (Exception e) { - throw new ShortViewConfigException( - "Parsing error in the short view config file.", e); - } finally { - try { - stream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - log.debug("Loaded " + m.size() + " statements"); - return m; - } - - /** - * Find all of the views. - */ - private Map createViewSpecs() - throws ShortViewConfigException { - Property rdfType = viewModel.getProperty(RDF_TYPE); - Property appliesTo = viewModel.getProperty(APPLIES_TO); - Property dataGetter = viewModel.getProperty(HAS_DATA_GETTER); - Property template = viewModel.getProperty(HAS_TEMPLATE); - Resource customView = viewModel.getResource(CUSTOM_VIEW); - - ResIterator views = viewModel.listResourcesWithProperty(rdfType, - customView); - try { - Map map = new HashMap(); - while (views.hasNext()) { - Resource view = views.next(); - List contextNames = getDataPropertyValues(view, - appliesTo, "context"); - List contexts = contextsFromNames(view, - contextNames); - List dataGetterUris = getObjectPropertyValues(view, - dataGetter, "data getter"); - String tn = getDataProperty(view, template); - map.put(view.getURI(), new ViewSpec(view.getURI(), contexts, - dataGetterUris, tn)); - } - return map; - } finally { - views.close(); - } - } - - /** - * Got a list of context names. Make sure that each one actually represents - * a known context. - */ - private List contextsFromNames(Resource view, - List contextNames) throws ShortViewConfigException { - List list = new ArrayList(); - for (String name : contextNames) { - ShortViewContext context = ShortViewContext.fromString(name); - if (context == null) { - throw new ShortViewConfigException("Unrecognized context '" - + name + "' for view '" + view.getURI() + "'"); - } - list.add(context); - } - return list; - } - - /** - * Create a map of classes to views. - */ - private Map> createClassMappings( - Map viewSpecsByUri) - throws ShortViewConfigException { - Property hasView = viewModel.getProperty(HAS_VIEW); - - StmtIterator stmts = viewModel.listStatements(null, hasView, - (RDFNode) null); - try { - Map> map = new HashMap>(); - while (stmts.hasNext()) { - Statement s = stmts.next(); - - String classUri = s.getSubject().getURI(); - - RDFNode node = s.getObject(); - if (!node.isResource()) { - throw new ShortViewConfigException("The hasCustomView" - + " property for '" + classUri - + "' must be a resource."); - } - String viewUri = node.asResource().getURI(); - - ViewSpec view = viewSpecsByUri.get(viewUri); - if (view == null) { - throw new ShortViewConfigException("On '" + classUri - + "', the view '" + viewUri + "' does not exist."); - } - - if (!map.containsKey(classUri)) { - map.put(classUri, new ArrayList()); - } - map.get(classUri).add(view); - } - return map; - } finally { - stmts.close(); - } - } - - private String getDataProperty(Resource subject, Property predicate) - throws ShortViewConfigException { - Statement s = viewModel.getProperty(subject, predicate); - if (s == null) { - throw new ShortViewConfigException("The required property '" - + predicate.getURI() + "' is not present for '" - + subject.getURI() + "'"); - } - RDFNode node = s.getObject(); - if (!node.isLiteral()) - throw new ShortViewConfigException("The value of '" - + predicate.getURI() + "' for '" + subject.getURI() - + "' must be a literal."); - return node.asLiteral().getString(); - } - - private List getDataPropertyValues(Resource subject, - Property predicate, String label) throws ShortViewConfigException { - StmtIterator stmts = viewModel.listStatements(subject, predicate, - (RDFNode) null); - try { - List list = new ArrayList(); - while (stmts.hasNext()) { - Statement stmt = stmts.next(); - RDFNode node = stmt.getObject(); - if (!node.isLiteral()) { - throw new ShortViewConfigException("The " + label - + " property for '" + subject.getURI() - + "' must be a literal."); - } - list.add(node.asLiteral().getString()); - } - return list; - } finally { - stmts.close(); - } - } - - private List getObjectPropertyValues(Resource subject, - Property predicate, String label) throws ShortViewConfigException { - StmtIterator stmts = viewModel.listStatements(subject, predicate, - (RDFNode) null); - try { - List list = new ArrayList(); - while (stmts.hasNext()) { - Statement stmt = stmts.next(); - RDFNode node = stmt.getObject(); - if (!node.isResource()) { - throw new ShortViewConfigException("The " + label - + " property for '" + subject.getURI() - + "' must be a resource."); - } - list.add(node.asResource().getURI()); - } - return list; - } finally { - stmts.close(); - } - } - - /** - * Return the template name and DataGetter instances associated with this - * class and this short view context. If none, return null. - */ - public TemplateAndDataGetters getShortViewProperties(VitroRequest vreq, - Individual individual, String classUri, String contextName) { - /* - * If we have a mapping for this class that applies to this context, - * construct the DataGetter instances and return them with the template. - */ - if (classUriToViewSpecs.containsKey(classUri)) { - for (ViewSpec view : classUriToViewSpecs.get(classUri)) { - for (ShortViewContext context : view.getContexts()) { - if (context.name().equalsIgnoreCase(contextName)) { - List dgList = new ArrayList(); - for (String dgUri : view.getDataGetterUris()) { - dgList.add(new SparqlQueryDataGetter(vreq, - viewModel, dgUri)); - } - return new TemplateAndDataGetters( - view.getTemplateName(), - dgList.toArray(new DataGetter[0])); - } - } - } - } - - /* - * Otherwise, check for this hard-coded kluge. Any class in the People - * class group gets a special view with preferred title. - */ - if ((BROWSE.name().equals(contextName)) - && (isClassInPeopleClassGroup(vreq.getWebappDaoFactory(), - classUri))) { - return new TemplateAndDataGetters("view-browse-people.ftl", - new FakeVivoPeopleDataGetter(vreq, individual.getURI())); - } - - /* - * Otherwise, no custom view. - */ - return null; - } - - private boolean isClassInPeopleClassGroup(WebappDaoFactory wadf, - String classUri) { - if (wadf == null) { - log.debug("isClassInPeopleClassGroup: WebappDaoFactory is null."); - return false; - } - - VClassDao vcDao = wadf.getVClassDao(); - if (vcDao == null) { - log.debug("isClassInPeopleClassGroup: VClassDao is null."); - return false; - } - - VClass vclass = vcDao.getVClassByURI(classUri); - if (vclass == null) { - log.debug("isClassInPeopleClassGroup: VClass is null."); - return false; - } - - String vclassGroupUri = vclass.getGroupURI(); - if (vclassGroupUri == null) { - log.debug("isClassInPeopleClassGroup: vclassGroupUri is null."); - return false; - } - - boolean isPeople = PEOPLE_CLASSGROUP_URI.equals(vclassGroupUri); - log.debug("isClassInPeopleClassGroup: isPeople = " + isPeople); - return isPeople; - } - - // ---------------------------------------------------------------------- - // Helper classes - // ---------------------------------------------------------------------- - - /** The info associated with a short view. */ - public static class TemplateAndDataGetters { - private final String templateName; - private final Set dataGetters; - - public TemplateAndDataGetters(String templateName, - DataGetter... dataGetters) { - this.templateName = templateName; - this.dataGetters = new HashSet( - Arrays.asList(dataGetters)); - } - - public String getTemplateName() { - return templateName; - } - - public Set getDataGetters() { - return dataGetters; - } - - @Override - public String toString() { - return "[template=" + templateName + ", dataGetters=" + dataGetters - + "]"; - } - - } - - /** The view specifications that we read from the config file. */ - private class ViewSpec { - private final String uri; - private final List contexts; - private final List dataGetterUris; - private final String templateName; - - public ViewSpec(String uri, List contexts, - List dataGetterUris, String templateName) { - this.uri = uri; - this.contexts = contexts; - this.dataGetterUris = dataGetterUris; - this.templateName = templateName; - } - - public List getContexts() { - return contexts; - } - - public List getDataGetterUris() { - return dataGetterUris; - } - - public String getTemplateName() { - return templateName; - } - - @Override - public String toString() { - return "ViewSpec[uri='" + uri + "', contexts=" + contexts - + ", dataGetterUris=" + dataGetterUris + ", templateName='" - + templateName + "']"; - } - - } - - /** A custom exception that says something was wrong with the config file. */ - public class ShortViewConfigException extends Exception { - public ShortViewConfigException(String message) { - super(message); - } - - public ShortViewConfigException(String message, Throwable cause) { - super(message, cause); - } - } - - private static final String PEOPLE_CLASSGROUP_URI = "http://vivoweb.org/ontology#vitroClassGrouppeople"; - - /** - * A special data getter to support the kluge case of browsing an individual - * that belongs to the People class group. - * - * A SPARQL query data getter that initializes itself from its own private - * "display model". The query finds a preferred title for the individual. - */ - private static class FakeVivoPeopleDataGetter extends SparqlQueryDataGetter { - // private static String QUERY_STRING = "" - // + "PREFIX obo: \n" - // + "PREFIX vcard: \n" - // + "SELECT ?pt \n" + "WHERE { \n" - // + " ?uri obo:ARG_2000028 ?vIndividual . \n" - // + " ?vIndividual vcard:hasTitle ?vTitle . \n" - // + " ?vTitle vcard:title ?pt . \n" + "} LIMIT 1"; - - /* - * UQAM-Optimization New query including Linguistic context - * and UQAM - In the filter, Case-insensitive language processing - */ - private static String QUERY_STRING_LANG(String lang) { - return "\n" - + "PREFIX obo: \n" - + "PREFIX vcard: \n" - + "SELECT ?pt \n" + "WHERE { \n" - + " ?uri obo:ARG_2000028 ?vIndividual . \n" - + " ?vIndividual vcard:hasTitle ?vTitle . \n" - + " ?vTitle vcard:title ?pt . \n" - // + " FILTER (lang(?pt) = '?langCtx' ) \n" old and buggy - + " FILTER (langMatches(lang(?pt), '" + lang+"' ) ) \n" - + " } LIMIT 1"; - } - private static final String FAKE_VIVO_PEOPLE_DATA_GETTER_URI = "http://FakeVivoPeopleDataGetter"; - - private static OntModel fakeDisplayModel = initializeFakeDisplayModel(); - - private static OntModel initializeFakeDisplayModel() { - OntModel m = ModelFactory - .createOntologyModel(OntModelSpec.OWL_DL_MEM); - - Resource dataGetter = m - .getResource(FAKE_VIVO_PEOPLE_DATA_GETTER_URI); - Property queryProperty = m.getProperty(DisplayVocabulary.QUERY); - Property saveToVarProperty = m - .getProperty(DisplayVocabulary.SAVE_TO_VAR); - - m.add(dataGetter, queryProperty, QUERY_STRING_LANG("en-US")); //UQAM-Optimization Using query with linguistic context - m.add(dataGetter, saveToVarProperty, "extra"); - return m; - } - - private String individualUri; - private VitroRequest vreq; - private ServletContext ctx; - private String langCtx = "en-US"; - - public FakeVivoPeopleDataGetter(VitroRequest vreq, String individualUri) { - super(vreq, initializeFakeDisplayModel(), "http://FakeVivoPeopleDataGetter"); - this.individualUri = individualUri; - this.vreq = vreq; - this.ctx = vreq.getSession().getServletContext(); - this.langCtx = vreq.getLocale().getLanguage(); // UQAM-Optimization add the linguistic context - if (!vreq.getLocale().getCountry().isEmpty()) { - this.langCtx += "-" + vreq.getLocale().getCountry(); - } - } - - @Override - public Map getData(Map pageData) { - Map parms = new HashMap<>(); - parms.put("uri", individualUri); - parms.put("langCtx", langCtx); //UQAM-Optimization add the linguistic context - return super.getData(parms); - } - - } + private static final Log log = LogFactory + .getLog(FakeApplicationOntologyService.class); + + public static final String FILE_OF_SHORT_VIEW_INFO = "/WEB-INF/resources/shortview_config.n3"; + + private static final String NS = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#"; + private static final String HAS_TEMPLATE = NS + "hasTemplate"; + private static final String CUSTOM_VIEW = NS + "customViewForIndividual"; + private static final String APPLIES_TO = NS + "appliesToContext"; + private static final String HAS_DATA_GETTER = NS + "hasDataGetter"; + private static final String HAS_VIEW = NS + "hasCustomView"; + private static final String RDF_TYPE = VitroVocabulary.RDF_TYPE; + + private final OntModel viewModel; + private final Map> classUriToViewSpecs; + + /** + * Load the model from the config file, and inspect it for Views and + * mappings. + * + * Keep the model - we'll need it when its time to create the DataGetters + * (on each request). + */ + public FakeApplicationOntologyService(ServletContext ctx) + throws ShortViewConfigException { + this.viewModel = createModelFromFile(ctx); + + Map viewSpecsByUri = createViewSpecs(); + this.classUriToViewSpecs = createClassMappings(viewSpecsByUri); + + if (log.isDebugEnabled()) { + log.debug("Mapping: " + classUriToViewSpecs); + } + } + + /** + * If we fail to parse the config file, use this constructor instead, to + * simulate an empty config file. + */ + public FakeApplicationOntologyService() { + this.viewModel = ModelFactory + .createOntologyModel(OntModelSpec.OWL_DL_MEM); + this.classUriToViewSpecs = new HashMap>(); + + log.debug("Created empty FakeApplicationOntologyService."); + } + + /** + * Load the short view config file into an OntModel. + */ + private OntModel createModelFromFile(ServletContext ctx) + throws ShortViewConfigException { + InputStream stream = ctx.getResourceAsStream(FILE_OF_SHORT_VIEW_INFO); + if (stream == null) { + throw new ShortViewConfigException("The short view config file " + + "doesn't exist in the servlet context: '" + + FILE_OF_SHORT_VIEW_INFO + "'"); + } + + OntModel m = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM); + try { + m.read(stream, null, "N3"); + } catch (Exception e) { + throw new ShortViewConfigException( + "Parsing error in the short view config file.", e); + } finally { + try { + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + log.debug("Loaded " + m.size() + " statements"); + return m; + } + + /** + * Find all of the views. + */ + private Map createViewSpecs() + throws ShortViewConfigException { + Property rdfType = viewModel.getProperty(RDF_TYPE); + Property appliesTo = viewModel.getProperty(APPLIES_TO); + Property dataGetter = viewModel.getProperty(HAS_DATA_GETTER); + Property template = viewModel.getProperty(HAS_TEMPLATE); + Resource customView = viewModel.getResource(CUSTOM_VIEW); + + ResIterator views = viewModel.listResourcesWithProperty(rdfType, + customView); + try { + Map map = new HashMap(); + while (views.hasNext()) { + Resource view = views.next(); + List contextNames = getDataPropertyValues(view, + appliesTo, "context"); + List contexts = contextsFromNames(view, + contextNames); + List dataGetterUris = getObjectPropertyValues(view, + dataGetter, "data getter"); + String tn = getDataProperty(view, template); + map.put(view.getURI(), new ViewSpec(view.getURI(), contexts, + dataGetterUris, tn)); + } + return map; + } finally { + views.close(); + } + } + + /** + * Got a list of context names. Make sure that each one actually represents + * a known context. + */ + private List contextsFromNames(Resource view, + List contextNames) throws ShortViewConfigException { + List list = new ArrayList(); + for (String name : contextNames) { + ShortViewContext context = ShortViewContext.fromString(name); + if (context == null) { + throw new ShortViewConfigException("Unrecognized context '" + + name + "' for view '" + view.getURI() + "'"); + } + list.add(context); + } + return list; + } + + /** + * Create a map of classes to views. + */ + private Map> createClassMappings( + Map viewSpecsByUri) + throws ShortViewConfigException { + Property hasView = viewModel.getProperty(HAS_VIEW); + + StmtIterator stmts = viewModel.listStatements(null, hasView, + (RDFNode) null); + try { + Map> map = new HashMap>(); + while (stmts.hasNext()) { + Statement s = stmts.next(); + + String classUri = s.getSubject().getURI(); + + RDFNode node = s.getObject(); + if (!node.isResource()) { + throw new ShortViewConfigException("The hasCustomView" + + " property for '" + classUri + + "' must be a resource."); + } + String viewUri = node.asResource().getURI(); + + ViewSpec view = viewSpecsByUri.get(viewUri); + if (view == null) { + throw new ShortViewConfigException("On '" + classUri + + "', the view '" + viewUri + "' does not exist."); + } + + if (!map.containsKey(classUri)) { + map.put(classUri, new ArrayList()); + } + map.get(classUri).add(view); + } + return map; + } finally { + stmts.close(); + } + } + + private String getDataProperty(Resource subject, Property predicate) + throws ShortViewConfigException { + Statement s = viewModel.getProperty(subject, predicate); + if (s == null) { + throw new ShortViewConfigException("The required property '" + + predicate.getURI() + "' is not present for '" + + subject.getURI() + "'"); + } + RDFNode node = s.getObject(); + if (!node.isLiteral()) + throw new ShortViewConfigException("The value of '" + + predicate.getURI() + "' for '" + subject.getURI() + + "' must be a literal."); + return node.asLiteral().getString(); + } + + private List getDataPropertyValues(Resource subject, + Property predicate, String label) throws ShortViewConfigException { + StmtIterator stmts = viewModel.listStatements(subject, predicate, + (RDFNode) null); + try { + List list = new ArrayList(); + while (stmts.hasNext()) { + Statement stmt = stmts.next(); + RDFNode node = stmt.getObject(); + if (!node.isLiteral()) { + throw new ShortViewConfigException("The " + label + + " property for '" + subject.getURI() + + "' must be a literal."); + } + list.add(node.asLiteral().getString()); + } + return list; + } finally { + stmts.close(); + } + } + + private List getObjectPropertyValues(Resource subject, + Property predicate, String label) throws ShortViewConfigException { + StmtIterator stmts = viewModel.listStatements(subject, predicate, + (RDFNode) null); + try { + List list = new ArrayList(); + while (stmts.hasNext()) { + Statement stmt = stmts.next(); + RDFNode node = stmt.getObject(); + if (!node.isResource()) { + throw new ShortViewConfigException("The " + label + + " property for '" + subject.getURI() + + "' must be a resource."); + } + list.add(node.asResource().getURI()); + } + return list; + } finally { + stmts.close(); + } + } + + /** + * Return the template name and DataGetter instances associated with this + * class and this short view context. If none, return null. + */ + public TemplateAndDataGetters getShortViewProperties(VitroRequest vreq, + Individual individual, String classUri, String contextName) { + /* + * If we have a mapping for this class that applies to this context, + * construct the DataGetter instances and return them with the template. + */ + if (classUriToViewSpecs.containsKey(classUri)) { + for (ViewSpec view : classUriToViewSpecs.get(classUri)) { + for (ShortViewContext context : view.getContexts()) { + if (context.name().equalsIgnoreCase(contextName)) { + List dgList = new ArrayList(); + for (String dgUri : view.getDataGetterUris()) { + dgList.add(new SparqlQueryDataGetter(vreq, + viewModel, dgUri)); + } + return new TemplateAndDataGetters( + view.getTemplateName(), + dgList.toArray(new DataGetter[0])); + } + } + } + } + + /* + * Otherwise, check for this hard-coded kluge. Any class in the People + * class group gets a special view with preferred title. + */ + if ((BROWSE.name().equals(contextName)) + && (isClassInPeopleClassGroup(vreq.getWebappDaoFactory(), + classUri))) { + return new TemplateAndDataGetters("view-browse-people.ftl", + new FakeVivoPeopleDataGetter(vreq, individual.getURI())); + } + + /* + * Otherwise, no custom view. + */ + return null; + } + + private boolean isClassInPeopleClassGroup(WebappDaoFactory wadf, + String classUri) { + if (wadf == null) { + log.debug("isClassInPeopleClassGroup: WebappDaoFactory is null."); + return false; + } + + VClassDao vcDao = wadf.getVClassDao(); + if (vcDao == null) { + log.debug("isClassInPeopleClassGroup: VClassDao is null."); + return false; + } + + VClass vclass = vcDao.getVClassByURI(classUri); + if (vclass == null) { + log.debug("isClassInPeopleClassGroup: VClass is null."); + return false; + } + + String vclassGroupUri = vclass.getGroupURI(); + if (vclassGroupUri == null) { + log.debug("isClassInPeopleClassGroup: vclassGroupUri is null."); + return false; + } + + boolean isPeople = PEOPLE_CLASSGROUP_URI.equals(vclassGroupUri); + log.debug("isClassInPeopleClassGroup: isPeople = " + isPeople); + return isPeople; + } + + // ---------------------------------------------------------------------- + // Helper classes + // ---------------------------------------------------------------------- + + /** The info associated with a short view. */ + public static class TemplateAndDataGetters { + private final String templateName; + private final Set dataGetters; + + public TemplateAndDataGetters(String templateName, + DataGetter... dataGetters) { + this.templateName = templateName; + this.dataGetters = new HashSet( + Arrays.asList(dataGetters)); + } + + public String getTemplateName() { + return templateName; + } + + public Set getDataGetters() { + return dataGetters; + } + + @Override + public String toString() { + return "[template=" + templateName + ", dataGetters=" + dataGetters + + "]"; + } + + } + + /** The view specifications that we read from the config file. */ + private class ViewSpec { + private final String uri; + private final List contexts; + private final List dataGetterUris; + private final String templateName; + + public ViewSpec(String uri, List contexts, + List dataGetterUris, String templateName) { + this.uri = uri; + this.contexts = contexts; + this.dataGetterUris = dataGetterUris; + this.templateName = templateName; + } + + public List getContexts() { + return contexts; + } + + public List getDataGetterUris() { + return dataGetterUris; + } + + public String getTemplateName() { + return templateName; + } + + @Override + public String toString() { + return "ViewSpec[uri='" + uri + "', contexts=" + contexts + + ", dataGetterUris=" + dataGetterUris + ", templateName='" + + templateName + "']"; + } + + } + + /** A custom exception that says something was wrong with the config file. */ + public class ShortViewConfigException extends Exception { + public ShortViewConfigException(String message) { + super(message); + } + + public ShortViewConfigException(String message, Throwable cause) { + super(message, cause); + } + } + + private static final String PEOPLE_CLASSGROUP_URI = "http://vivoweb.org/ontology#vitroClassGrouppeople"; + + /** + * A special data getter to support the kluge case of browsing an individual + * that belongs to the People class group. + * + * A SPARQL query data getter that initializes itself from its own private + * "display model". The query finds a preferred title for the individual. + */ + private static class FakeVivoPeopleDataGetter extends SparqlQueryDataGetter { + // private static String QUERY_STRING = "" + // + "PREFIX obo: \n" + // + "PREFIX vcard: \n" + // + "SELECT ?pt \n" + "WHERE { \n" + // + " ?uri obo:ARG_2000028 ?vIndividual . \n" + // + " ?vIndividual vcard:hasTitle ?vTitle . \n" + // + " ?vTitle vcard:title ?pt . \n" + "} LIMIT 1"; + + /* + * UQAM-Optimization New query including Linguistic context + */ + private static String QUERY_STRING_LANG(String lang) { + return "" + + "PREFIX obo: \n" + + "PREFIX vcard: \n" + + "SELECT ?pt \n" + "WHERE { \n" + + " ?uri obo:ARG_2000028 ?vIndividual . \n" + + " ?vIndividual vcard:hasTitle ?vTitle . \n" + + " ?vTitle vcard:title ?pt . \n" + + " FILTER (langMatches(lang(?pt), '" + lang + "')) \n" + + " } LIMIT 1"; + } + + private static final String FAKE_VIVO_PEOPLE_DATA_GETTER_URI = "http://FakeVivoPeopleDataGetter"; + + private static OntModel fakeDisplayModel = initializeFakeDisplayModel(); + + private static OntModel initializeFakeDisplayModel() { + OntModel m = ModelFactory + .createOntologyModel(OntModelSpec.OWL_DL_MEM); + + Resource dataGetter = m + .getResource(FAKE_VIVO_PEOPLE_DATA_GETTER_URI); + Property queryProperty = m.getProperty(DisplayVocabulary.QUERY); + Property saveToVarProperty = m + .getProperty(DisplayVocabulary.SAVE_TO_VAR); + + m.add(dataGetter, queryProperty, QUERY_STRING_LANG("en-US")); //UQAM-Optimization Using query with linguistic context + m.add(dataGetter, saveToVarProperty, "extra"); + return m; + } + + private String individualUri; + private VitroRequest vreq; + private ServletContext ctx; + private String langCtx = "en-US"; + + public FakeVivoPeopleDataGetter(VitroRequest vreq, String individualUri) { + super(vreq, initializeFakeDisplayModel(), "http://FakeVivoPeopleDataGetter"); + this.individualUri = individualUri; + this.vreq = vreq; + this.ctx = vreq.getSession().getServletContext(); + this.langCtx = vreq.getLocale().getLanguage(); // UQAM-Optimization add the linguistic context + if (!vreq.getLocale().getCountry().isEmpty()) { + this.langCtx += "-" + vreq.getLocale().getCountry(); + } + } + + @Override + public Map getData(Map pageData) { + Map parms = new HashMap<>(); + parms.put("uri", individualUri); + parms.put("langCtx", langCtx); //UQAM-Optimization add the linguistic context + + return super.getData(parms); + } + + } } From a1de03f2f5a5d557f8cda65736668482c35e8e2e Mon Sep 17 00:00:00 2001 From: William Welling Date: Tue, 14 Feb 2023 11:34:19 -0600 Subject: [PATCH 3/3] Use SPARQL template and context map to substitute langCtx --- .../shortview/FakeApplicationOntologyService.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java index 96ee072559..5ef4ca96b1 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/services/shortview/FakeApplicationOntologyService.java @@ -456,17 +456,15 @@ private static class FakeVivoPeopleDataGetter extends SparqlQueryDataGetter { /* * UQAM-Optimization New query including Linguistic context */ - private static String QUERY_STRING_LANG(String lang) { - return "" + private static String QUERY_STRING_LANG = "" + "PREFIX obo: \n" + "PREFIX vcard: \n" + "SELECT ?pt \n" + "WHERE { \n" + " ?uri obo:ARG_2000028 ?vIndividual . \n" + " ?vIndividual vcard:hasTitle ?vTitle . \n" + " ?vTitle vcard:title ?pt . \n" - + " FILTER (langMatches(lang(?pt), '" + lang + "')) \n" + + " FILTER (langMatches(lang(?pt), '?langCtx')) \n" + " } LIMIT 1"; - } private static final String FAKE_VIVO_PEOPLE_DATA_GETTER_URI = "http://FakeVivoPeopleDataGetter"; @@ -482,7 +480,7 @@ private static OntModel initializeFakeDisplayModel() { Property saveToVarProperty = m .getProperty(DisplayVocabulary.SAVE_TO_VAR); - m.add(dataGetter, queryProperty, QUERY_STRING_LANG("en-US")); //UQAM-Optimization Using query with linguistic context + m.add(dataGetter, queryProperty, QUERY_STRING_LANG); //UQAM-Optimization Using query with linguistic context m.add(dataGetter, saveToVarProperty, "extra"); return m; }