Merge branch 'maint-rel-1.6' into develop

This commit is contained in:
j2blake 2013-11-19 15:26:28 -05:00
commit 30fa123948
5 changed files with 174 additions and 7 deletions

View file

@ -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"));
}

View file

@ -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);
}

View file

@ -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<Locale> getCandidateLocales(String baseName, Locale locale) {
// Find the list of Locales that would normally be returned.
List<Locale> usualList = super
.getCandidateLocales(baseName, locale);
// If our "selectable locales" include no approximate matches that
// are not already in the list, we're done.
SortedSet<Locale> 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<Locale> 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<Locale> findApproximateMatches(Locale locale) {
SortedSet<Locale> 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<Locale> {
@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;
}
}
}

View file

@ -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<Locale> 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<Locale> getSelectableLocales(ServletContext ctx) {
Object ctxInfo = ctx.getAttribute(ATTRIBUTE_NAME);
if (ctxInfo instanceof ContextSelectedLocale) {
List<Locale> 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() {

View file

@ -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<Locale> 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<Locale> selectable,
String... expected) {
SelectedLocale.setSelectableLocales(ctx, selectable);
List<Locale> expectedLocales = locales(expected);
I18n.ThemeBasedControl control = new I18n.ThemeBasedControl(ctx,
"bogusThemeDirectory");
List<Locale> actualLocales = control.getCandidateLocales(
"bogusBaseName", locale(requested));
assertEquals("Expected locales", expectedLocales, actualLocales);
}
private static List<Locale> locales(String... strings) {
List<Locale> 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);
}
}