From 5212b29e50ebb31e85e940d1b10b8db22432ef58 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 19 Nov 2013 13:28:54 -0500 Subject: [PATCH 1/3] ensuring that inverse gets deleted when forward property gets deleted --- .../mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index ecdc2bfbc..7d0e42509 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -71,8 +71,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } public void deleteObjectProperty(String propertyURI) { - ObjectProperty op = new ObjectProperty(); - op.setURI(propertyURI); + ObjectProperty op = getObjectPropertyByURI(propertyURI); deleteObjectProperty(op); } From 4e9e4216dade677c8ca73f40240590a7ac9aea63 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Tue, 19 Nov 2013 13:29:32 -0500 Subject: [PATCH 2/3] removing a mention of vivo from vitro --- .../freemarker/SimpleReasonerRecomputeController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SimpleReasonerRecomputeController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SimpleReasonerRecomputeController.java index fd16e2a75..47181cf4b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SimpleReasonerRecomputeController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SimpleReasonerRecomputeController.java @@ -56,7 +56,7 @@ public class SimpleReasonerRecomputeController extends FreemarkerHttpServlet { "SimpleReasonerRecomputController.Recomputer"); thread.setWorkLevel(WORKING); thread.start(); - messageStr = "Recompute of inferences started. See vivo log for further details."; + messageStr = "Recompute of inferences started. See log for further details."; } else { body.put("formAction", UrlBuilder.getUrl("/RecomputeInferences")); } From cd0cb50798949d9fce5e15c623eaaf0d2bcae8ed Mon Sep 17 00:00:00 2001 From: j2blake Date: Tue, 19 Nov 2013 15:25:43 -0500 Subject: [PATCH 3/3] VIVO-533 When loading properties files, mimic the language filtering of the RDFService. --- .../mannlib/vitro/webapp/i18n/I18n.java | 70 +++++++++++++- .../webapp/i18n/selection/SelectedLocale.java | 13 ++- .../mannlib/vitro/webapp/i18n/I18nTest.java | 93 +++++++++++++++++++ 3 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 webapp/test/edu/cornell/mannlib/vitro/webapp/i18n/I18nTest.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18n.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18n.java index 05758f26b..43d33c55e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18n.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18n.java @@ -3,10 +3,14 @@ package edu.cornell.mannlib.vitro.webapp.i18n; import java.io.IOException; +import java.util.Comparator; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.concurrent.atomic.AtomicReference; import javax.servlet.ServletContext; @@ -16,6 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale; import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings; import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings.Keys; @@ -128,7 +133,7 @@ public class I18n { * If we are in development mode, clear the cache on each request. */ private void checkDevelopmentMode(HttpServletRequest req) { - if (DeveloperSettings.getBean(req).getBoolean(Keys.I18N_DEFEAT_CACHE) ) { + if (DeveloperSettings.getBean(req).getBoolean(Keys.I18N_DEFEAT_CACHE)) { log.debug("In development mode - clearing the cache."); clearCacheOnRequest(req); } @@ -167,7 +172,7 @@ public class I18n { * Instead of looking in the classpath, look in the theme i18n directory and * the application i18n directory. */ - private static class ThemeBasedControl extends ResourceBundle.Control { + static class ThemeBasedControl extends ResourceBundle.Control { private static final String BUNDLE_DIRECTORY = "i18n/"; private final ServletContext ctx; private final String themeDirectory; @@ -215,6 +220,52 @@ public class I18n { themeI18nPath, this); } + /** + * When creating the chain of acceptable Locales, include approximate + * matches before giving up and using the root Locale. + * + * Check the list of supported Locales to see if any have the same + * language but different region. If we find any, sort them and insert + * them into the usual result list, just before the root Locale. + */ + @Override + public List getCandidateLocales(String baseName, Locale locale) { + // Find the list of Locales that would normally be returned. + List usualList = super + .getCandidateLocales(baseName, locale); + + // If our "selectable locales" include no approximate matches that + // are not already in the list, we're done. + SortedSet approximateMatches = findApproximateMatches(locale); + approximateMatches.removeAll(usualList); + if (approximateMatches.isEmpty()) { + return usualList; + } + + // Otherwise, insert those approximate matches into the list just + // before the ROOT locale. + List mergedList = new LinkedList<>(usualList); + int rootLocaleHere = mergedList.indexOf(Locale.ROOT); + if (rootLocaleHere == -1) { + mergedList.addAll(approximateMatches); + } else { + mergedList.addAll(rootLocaleHere, approximateMatches); + } + return mergedList; + } + + private SortedSet findApproximateMatches(Locale locale) { + SortedSet set = new TreeSet<>(new LocaleComparator()); + + for (Locale l : SelectedLocale.getSelectableLocales(ctx)) { + if (locale.getLanguage().equals(l.getLanguage())) { + set.add(l); + } + } + + return set; + } + /** * The documentation for ResourceBundle.Control.newBundle() says I * should throw these exceptions. @@ -235,5 +286,20 @@ public class I18n { "format must be one of these: " + FORMAT_DEFAULT); } } + + } + + private static class LocaleComparator implements Comparator { + @Override + public int compare(Locale o1, Locale o2) { + int c = o1.getLanguage().compareTo(o2.getLanguage()); + if (c == 0) { + c = o1.getCountry().compareTo(o2.getCountry()); + if (c == 0) { + c = o1.getVariant().compareTo(o2.getVariant()); + } + } + return c; + } } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/SelectedLocale.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/SelectedLocale.java index 7ae4586cb..8356af109 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/SelectedLocale.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/SelectedLocale.java @@ -2,6 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.i18n.selection; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -124,7 +125,14 @@ public abstract class SelectedLocale { * an empty list, but never returns null. */ public static List getSelectableLocales(HttpServletRequest req) { - ServletContext ctx = req.getSession().getServletContext(); + return getSelectableLocales(req.getSession().getServletContext()); + } + + /** + * Get the list of selectable Locales from the servlet context. May return + * an empty list, but never returns null. + */ + public static List getSelectableLocales(ServletContext ctx) { Object ctxInfo = ctx.getAttribute(ATTRIBUTE_NAME); if (ctxInfo instanceof ContextSelectedLocale) { List selectableLocales = ((ContextSelectedLocale) ctxInfo) @@ -164,7 +172,8 @@ public abstract class SelectedLocale { } this.forcedLocale = null; - this.selectableLocales = selectableLocales; + this.selectableLocales = Collections + .unmodifiableList(new ArrayList<>(selectableLocales)); } public Locale getForcedLocale() { diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/i18n/I18nTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/i18n/I18nTest.java new file mode 100644 index 000000000..db051f961 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/i18n/I18nTest.java @@ -0,0 +1,93 @@ +package edu.cornell.mannlib.vitro.webapp.i18n; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.junit.Before; +import org.junit.Test; + +import stubs.javax.servlet.ServletContextStub; +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale; + +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +/** + * Test the I18N functionality. + * + * Start by checking the logic that finds approximate matches for + * language-specific property files. + */ +public class I18nTest extends AbstractTestClass { + private static final List SELECTABLE_LOCALES = locales("es_MX", + "en_US"); + + ServletContextStub ctx; + + @Before + public void setup() { + ctx = new ServletContextStub(); + } + + @Test + public void noMatchOnLanguageRegion() { + assertLocales("fr_CA", SELECTABLE_LOCALES, "fr_CA", "fr", ""); + } + + @Test + public void noMatchOnLanguage() { + assertLocales("fr", SELECTABLE_LOCALES, "fr", ""); + } + + @Test + public void noMatchOnRoot() { + assertLocales("", SELECTABLE_LOCALES, ""); + } + + @Test + public void matchOnLanguageRegion() { + assertLocales("es_ES", SELECTABLE_LOCALES, "es_ES", "es", "es_MX", ""); + } + + @Test + public void matchOnLanguage() { + assertLocales("es", SELECTABLE_LOCALES, "es", "es_MX", ""); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + private void assertLocales(String requested, List selectable, + String... expected) { + SelectedLocale.setSelectableLocales(ctx, selectable); + List expectedLocales = locales(expected); + + I18n.ThemeBasedControl control = new I18n.ThemeBasedControl(ctx, + "bogusThemeDirectory"); + List actualLocales = control.getCandidateLocales( + "bogusBaseName", locale(requested)); + + assertEquals("Expected locales", expectedLocales, actualLocales); + } + + private static List locales(String... strings) { + List locales = new ArrayList<>(); + for (String s : strings) { + locales.add(locale(s)); + } + return locales; + } + + private static Locale locale(String s) { + String[] parts = s.split("_"); + String language = (parts.length > 0) ? parts[0] : ""; + String country = (parts.length > 1) ? parts[1] : ""; + String variant = (parts.length > 2) ? parts[2] : ""; + return new Locale(language, country, variant); + } + +}