From 6d7f8e05c8feda81e05a5a9adbea7669410e33ec Mon Sep 17 00:00:00 2001 From: j2blake Date: Thu, 9 May 2013 12:24:01 -0400 Subject: [PATCH] VIVO-84 Use language filtering on the display model This doesn't answer the questions: 1) How do we edit new pages or existing pages? 2) What is the generalized procedure for adding another language? --- .../vitro/webapp/controller/VitroRequest.java | 34 ++------ .../webapp/filters/VitroRequestPrep.java | 21 +++++ .../filters/WebappDaoFactorySDBPrep.java | 31 +++---- .../filter/LanguageFilteringRDFService.java | 5 ++ .../filter/LanguageFilteringUtils.java | 81 +++++++++++++++++++ 5 files changed, 127 insertions(+), 45 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java index 88416f911..53587eae2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java @@ -214,32 +214,14 @@ public class VitroRequest extends HttpServletRequestWrapper { } //Get the display and editing configuration model - public OntModel getDisplayModel(){ - //bdc34: I have no idea what the correct way to get this model is - - //try from the request - if( _req.getAttribute("displayOntModel") != null ){ - return (OntModel) _req.getAttribute(DISPLAY_ONT_MODEL); - - //try from the session - } else { - HttpSession session = _req.getSession(false); - if( session != null ){ - if( session.getAttribute(DISPLAY_ONT_MODEL) != null ){ - return (OntModel) session.getAttribute(DISPLAY_ONT_MODEL); - - //try from the context - }else{ - if( session.getServletContext().getAttribute(DISPLAY_ONT_MODEL) != null){ - return (OntModel)session.getServletContext().getAttribute(DISPLAY_ONT_MODEL); - } - } - } - } - - //nothing worked, could not find display model - log.error("No display model could be found."); - return null; + public OntModel getDisplayModel(){ + Object value = _req.getAttribute(DISPLAY_ONT_MODEL); + if (value instanceof OntModel) { + return (OntModel) value; + } else { + log.error("No display model on the VitroRequest. Expecting an OntModel but found " + value); + return null; + } } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java index f1d7a6e71..3f58cd191 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java @@ -11,6 +11,7 @@ import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_MODEL_P import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_TBOX_MODEL_PARAM; import java.io.IOException; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -47,10 +48,14 @@ import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.FilterFactory; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HideFromDisplayByPolicyFilter; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; +import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringRDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringUtils; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; /** @@ -133,6 +138,22 @@ public class VitroRequestPrep implements Filter { log.debug("Found a WebappDaoFactory in the session and using it for this request"); } + // Set up the DisplayModel, with language filtering if appropriate. + OntModel displayModel; + Object displayModelObject = req.getSession().getAttribute(DISPLAY_ONT_MODEL); + if (displayModelObject instanceof OntModel) { + displayModel = (OntModel) displayModelObject; + } else { + displayModel = (OntModel) _context.getAttribute(DISPLAY_ONT_MODEL); + } + + if (Boolean.valueOf(ConfigurationProperties.getBean(vreq).getProperty( + "RDFService.languageFilter", "true"))) { + displayModel = LanguageFilteringUtils.wrapOntModelInALanguageFilter(displayModel, req); + } + vreq.setAttribute(DISPLAY_ONT_MODEL, displayModel); + + //Do model switching and replace the WebappDaoFactory with //a different version if requested by parameters wdf = checkForModelSwitching(vreq, wdf); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java index 4bb7fda8e..5dd3652f7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java @@ -3,10 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.filters; import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; -import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -22,6 +19,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.ModelFactory; @@ -38,6 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetM import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringRDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringUtils; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; public class WebappDaoFactorySDBPrep implements Filter { @@ -88,18 +87,10 @@ public class WebappDaoFactorySDBPrep implements Filter { String defaultNamespace = (String) _ctx.getAttribute("defaultNamespace"); WebappDaoFactory wadf = null; VitroRequest vreq = new VitroRequest((HttpServletRequest) request); - - List langs = new ArrayList(); + + log.debug("Accept-Language: " + vreq.getHeader("Accept-Language")); + List langs = LanguageFilteringUtils.localesToLanguages(vreq.getLocales()); - log.debug("Accept-Language: " + vreq.getHeader("Accept-Language")); - Enumeration locs = vreq.getLocales(); - while (locs.hasMoreElements()) { - Locale locale = locs.nextElement(); - langs.add(locale.toString().replace("_", "-")); - } - if (langs.isEmpty()) { - langs.add("en"); - } WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); config.setDefaultNamespace(defaultNamespace); config.setPreferredLanguages(langs); @@ -110,12 +101,14 @@ public class WebappDaoFactorySDBPrep implements Filter { RDFService unfilteredRDFService = factory.getShortTermRDFService(); RDFService rdfService = null; - if (!"false".equals( - ConfigurationProperties.getBean(vreq).getProperty( - "RDFService.languageFilter", "true"))) { - rdfService = new LanguageFilteringRDFService(unfilteredRDFService, langs); + if (Boolean.valueOf(ConfigurationProperties.getBean(vreq).getProperty( + "RDFService.languageFilter", "true"))) { + rdfService = new LanguageFilteringRDFService(unfilteredRDFService, langs); + oms = LanguageFilteringUtils.replaceDisplayModelInSelector(oms, + LanguageFilteringUtils.wrapOntModelInALanguageFilter(oms.getDisplayModel(), request)); + baseOms = LanguageFilteringUtils.replaceDisplayModelInSelector(baseOms, oms.getDisplayModel()); } else { - rdfService = unfilteredRDFService; + rdfService = unfilteredRDFService; } Dataset dataset = new RDFServiceDataset(rdfService); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java index 1df269857..936462153 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java @@ -8,8 +8,10 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Enumeration; import java.util.Iterator; import java.util.List; +import java.util.Locale; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -368,17 +370,20 @@ public class LanguageFilteringRDFService implements RDFService { int index = langs.indexOf(lang); if (index >= 0) { + log.debug("languageIndex for '" + lang + "' is " + index); return index; } if (lang.length() > 2) { index = langs.indexOf(lang.substring(0, 2)); if (index >= 0) { + log.debug("languageIndex for '" + lang + "' is " + index + inexactMatchPenalty); return index + inexactMatchPenalty; } } if (lang.isEmpty()) { + log.debug("languageIndex for '" + lang + "' is " + noLanguage); return noLanguage; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java new file mode 100644 index 000000000..aae04c1b5 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java @@ -0,0 +1,81 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.filter; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; + +import javax.servlet.ServletRequest; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.rdf.model.ModelFactory; + +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; + +/** + * Some methods that will come in handy when dealing with Language Filtering + */ +public class LanguageFilteringUtils { + + /** + * Take an Enumeration of Locale objects, such as we might get from a + * request, and convert to a List of langauage strings, such as are needed + * by the LanguageFilteringRDFService. + * + * While converting, change all underscores (as in Locale names) to hyphens + * (as in RDF language specifiers). + */ + public static List localesToLanguages(Enumeration locales) { + List langs = new ArrayList<>(); + while (locales.hasMoreElements()) { + Locale locale = (Locale) locales.nextElement(); + langs.add(locale.toString().replace("_", "-")); + } + if (langs.isEmpty()) { + langs.add("en"); + } + return langs; + + } + + /** + * Make a new OntModelSelector that containing a new display model and all + * of the other models in the original OntModelSelector. + */ + public static OntModelSelector replaceDisplayModelInSelector( + OntModelSelector oldOms, OntModel newDisplayModel) { + OntModelSelectorImpl newOms = new OntModelSelectorImpl(); + newOms.setABoxModel(oldOms.getABoxModel()); + newOms.setApplicationMetadataModel(oldOms.getApplicationMetadataModel()); + newOms.setDisplayModel(newDisplayModel); + newOms.setFullModel(oldOms.getFullModel()); + newOms.setTBoxModel(oldOms.getTBoxModel()); + newOms.setUserAccountsModel(oldOms.getUserAccountsModel()); + return newOms; + } + + /** + * Add a Language Filtering layer to an OntModel by treating it as an RDFService. + */ + public static OntModel wrapOntModelInALanguageFilter(OntModel rawModel, + ServletRequest req) { + /** This is some nasty layering. Could we do this more easily? */ + List languages = localesToLanguages(req.getLocales()); + return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, + RDFServiceGraph.createRDFServiceModel( + new RDFServiceGraph( + new LanguageFilteringRDFService( + new RDFServiceModel(rawModel), languages)))); + } + + private LanguageFilteringUtils() { + // Nothing to instantiate + } + +}