/*
* Copyright 2003-2010 Tufts University Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package edu.tufts.vue.preferences.implementations;
import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Locale;
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.prefs.Preferences;
import javax.swing.ListModel;
import javax.swing.event.ListSelectionEvent;
import tufts.vue.LWComponent;
import tufts.vue.VUE;
import tufts.vue.VueResources;
/**
* @author Brian Goodmon
*/
public class LanguagePreference extends edu.tufts.vue.preferences.generics.GenericListPreference {
protected static final org.apache.log4j.Logger
Log = org.apache.log4j.Logger.getLogger(LanguagePreference.class);
protected String category;
protected String key;
protected String name;
protected String description;
protected String defaultValue;
protected boolean ignoreListSelectionEvent = false;
public static LanguagePreference create(String category, String key, String name, String desc, String defaultValue, boolean showInUI) {
return new LanguagePreference(category, key, name, desc, defaultValue, showInUI);
}
public static LanguagePreference create(String category, String key, String name, String desc, String defaultValue) {
return new LanguagePreference(category, key, name, desc, defaultValue, true);
}
public static LanguagePreference create(String category, String key, String name, String desc) {
return new LanguagePreference(category, key, name, desc, null, true);
}
private LanguagePreference(String category, String key, String name, String desc, String defaultValue, boolean showInUI) {
super();
this.category = category;
this.key = key;
this.name = name;
this.description = desc;
this.defaultValue = (defaultValue != null ? defaultValue : fixCaps(Locale.getDefault().getDisplayName()));
if (showInUI) {
edu.tufts.vue.preferences.PreferencesManager.registerPreference(this);
}
loadList = new Runnable() {
public void run() {
String filename = null;
try {
TreeSet<StringPair> foundLocales = new TreeSet<StringPair>();
ClassLoader loader = ClassLoader.getSystemClassLoader();
URL url = loader.getResource("tufts/vue/");
if (url != null) {
filename = URLDecoder.decode(url.getFile(), "UTF-8");
filename = filename.substring(filename.indexOf("/"), filename.lastIndexOf("!"));
File file = new File(filename);
JarFile jar = new JarFile(file);
Enumeration<JarEntry>
jarEntries = jar.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String name = jarEntry.getName();
if (name.indexOf("VueResources_") != -1 && name.indexOf("__") == -1) {
int languageIndex = name.indexOf("_") + 1;
String langCountry = name.substring(languageIndex);
String language = langCountry.substring(0, 2);
int countryIndex = langCountry.lastIndexOf("_") + 1;
String country = (countryIndex == 0 ? null : langCountry.substring(countryIndex, countryIndex + 2));
Locale foundLocale = (country == null ? new Locale(language) : new Locale(language, country));
String foundLanguage = foundLocale.getLanguage(),
localizedDisplayName = fixCaps(foundLocale.getDisplayName(new Locale(foundLanguage)));
if (localizedDisplayName.length() > 0) {
// TreeSet is used to collect found locales because it doesn't add duplicates, and
// it automatically orders its members.
String foundCountry = foundLocale.getCountry();
foundLocales.add(new StringPair(localizedDisplayName, foundLanguage + (foundCountry.length() < 2 ? "" : ("_" + foundCountry))));
}
}
}
}
list.setListData(foundLocales.toArray());
// Find the list item previously chosen as the preference (or the default) and select it.
String prefValue = getValue();
ListModel model = list.getModel();
int modelSize = model.getSize();
for (int index = 0; index < modelSize; index++) {
if (prefValue.equals(((StringPair)model.getElementAt(index)).getValue())) {
ignoreListSelectionEvent = true;
list.setSelectedIndex(index);
break;
}
}
} catch (Exception ex) {
Log.error("loadList exception loading " + filename + ": " + ex);
}
}
};
}
protected void finalize() throws Throwable {
try {
category = null;
key = null;
name = null;
description = null;
defaultValue = null;
}
finally {
super.finalize();
}
}
public void setLocalizedStringsAndRegister() {
// An instance of this class is created by VueResources to get the VUE-specific preferred language.
// At the time of its creation the title and description can't be set because they are localized and
// can't be fetched until VueResources is initialized. After VueResources initializes it will call
// this method to set the title and description, and to register the class with PreferencesManager.
if (name == null) {
name = VueResources.getString("preferences.language.title");
}
if (description == null) {
description = VueResources.getString("preferences.language.description");
}
edu.tufts.vue.preferences.PreferencesManager.registerPreference(this);
}
public String getCategoryKey() {
return category;
}
public String getTitle() {
return name;
}
public String getDescription() {
return description;
}
public String getPrefName() {
return category + "." + key;
}
public String getDefaultValue() {
return defaultValue;
}
public String getCode() {
return Preferences.userNodeForPackage(getPrefRoot()).get(getPrefName() + ".code",
Preferences.systemNodeForPackage(getPrefRoot()).get(getPrefName() + ".code",
Locale.getDefault().toString()));
}
public void setCode(String string) {
Preferences p = Preferences.userNodeForPackage(getPrefRoot());
p.put(getPrefName() + ".code", string);
}
public String getLanguage() {
return getCode().substring(0, 2);
}
public String getCountry() {
String code = getCode();
return (code.length() < 5 ? "" : getCode().substring(3, 5));
}
public String fixCaps(String name) {
//Fix the improperly capitalized names returned by Locale.getDisplayName(Locale).
int nameLength = name.length();
return (nameLength < 1 ? "" : name.substring(0, 1).toUpperCase() +
(nameLength < 2 ? "" : name.substring(1)));
}
/** interface ListSelectionListener */
public void valueChanged(ListSelectionEvent event) {
if (!event.getValueIsAdjusting()) {
StringPair selected = (StringPair)list.getSelectedValue();
if (ignoreListSelectionEvent) {
// If the ListSelectionListener event was caused by loadList it should be ignored and
// NOT set the value/code in the preference (because it might be selecting the default
// value, which shouldn't be written to the backing store).
ignoreListSelectionEvent = false;
} else {
if (selected != null) {
setValue(selected.getValue());
setCode(selected.getCode());
}
}
}
}
public class StringPair implements Comparable<StringPair> {
String value = null,
code = null;
public StringPair(String value, String code) {
this.value = value;
this.code = code;
}
public String getValue() {
return value;
}
public String getCode() {
return code;
}
public String toString() {
return value;
}
/** interface Comparable<StringPair>
* Implemented so that a StringPair can be added to a TreeSet.
*/
public int compareTo(StringPair pair) {
return value.compareTo(pair.getValue());
}
}
}