/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.fib.model;
import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import java.util.logging.Logger;
import org.openflexo.localization.Language;
import org.openflexo.localization.LocalizedDelegate;
import org.openflexo.toolbox.StringUtils;
public class FIBLocalizedDictionary extends FIBModelObject implements LocalizedDelegate {
private static final Logger logger = Logger.getLogger(FIBLocalizedDictionary.class.getPackage().getName());
private FIBComponent _component;
private Vector<FIBLocalizedEntry> _entries;
private Hashtable<Language, Hashtable<String, String>> _values;
private Vector<DynamicEntry> dynamicEntries = null;
private boolean isSearchingNewEntries = false;
public FIBLocalizedDictionary() {
_entries = new Vector<FIBLocalizedEntry>();
_values = new Hashtable<Language, Hashtable<String, String>>();
}
public FIBComponent getComponent() {
return _component;
}
public void setComponent(FIBComponent component) {
_component = component;
}
public Vector<FIBLocalizedEntry> getEntries() {
return _entries;
}
public void setEntries(Vector<FIBLocalizedEntry> someEntries) {
_entries = someEntries;
}
public void addToEntries(FIBLocalizedEntry entry) {
entry.setLocalizedDictionary(this);
_entries.add(entry);
// logger.info("Add entry key:"+entry.getKey()+" lang="+entry.getLanguage()+" value:"+entry.getValue());
Language lang = Language.retrieveLanguage(entry.getLanguage());
if (lang == null) {
logger.warning("Undefined language: " + entry.getLanguage());
return;
}
getDictForLang(lang).put(entry.getKey(), entry.getValue());
}
public void removeFromEntries(FIBLocalizedEntry entry) {
entry.setLocalizedDictionary(null);
_entries.remove(entry);
}
public void append(FIBLocalizedDictionary aDict) {
if (aDict == null) {
return;
}
for (FIBLocalizedEntry entry : aDict.getEntries()) {
addToEntries(entry);
}
}
private FIBLocalizedEntry getEntry(Language language, String key) {
for (FIBLocalizedEntry entry : getEntries()) {
if (Language.retrieveLanguage(entry.getLanguage()) == language && key.equals(entry.getKey())) {
return entry;
}
}
return null;
}
private Hashtable<String, String> getDictForLang(Language lang) {
Hashtable<String, String> dict = _values.get(lang);
if (dict == null) {
dict = new Hashtable<String, String>();
_values.put(lang, dict);
}
return dict;
}
/*public String getDefaultValue(String key, Language language) {
if (mainLocalizer != null) {
return mainLocalizer.getLocalizedForKeyAndLanguage(key, language);
}
// Otherwise, don't know what to do, return key
return key;
// logger.info("Searched default value for key "+key+" return "+FlexoLocalization.localizedForKey(key));
// return FlexoLocalization.localizedForKeyAndLanguage(key, language, false, false);
}*/
@Override
public String getLocalizedForKeyAndLanguage(String key, Language language) {
if (key == null || StringUtils.isEmpty(key)) {
return null;
}
// if (isSearchingNewEntries) logger.info("-------> called localizedForKeyAndLanguage() key="+key+" lang="+language);
return getDictForLang(language).get(key);
/*String returned = getDictForLang(language).get(key);
if (returned == null) {
String defaultValue = getDefaultValue(key, language);
if (handleNewEntry(key, language)) {
if (!key.equals(defaultValue)) {
addToEntries(new FIBLocalizedEntry(this, key, language.getName(), defaultValue));
logger.fine("FIBLocalizedDictionary: store value " + defaultValue + " for key " + key + " for language " + language);
} else {
getDictForLang(language).put(key, defaultValue);
logger.fine("FIBLocalizedDictionary: undefined value for key " + key + " for language " + language);
}
// dynamicEntries = null;
}
return defaultValue;
}
return returned;*/
}
public void setLocalizedForKeyAndLanguage(String key, String value, Language language) {
if (value == null) {
value = key;
}
getDictForLang(language).put(key, value);
FIBLocalizedEntry entry = getEntry(language, key);
if (entry == null) {
addToEntries(new FIBLocalizedEntry(this, key, language.getName(), value));
} else {
entry.setValue(value);
}
}
@Override
public boolean handleNewEntry(String key, Language language) {
// logger.warning(">>>>>>>>>>>>>>>>>>>>> Cannot find key "+key+" for language "+language);
return isSearchingNewEntries;
// return false;
}
@Override
public FIBComponent getRootComponent() {
return getComponent().getRootComponent();
}
public class DynamicEntry {
private String key;
public DynamicEntry(String aKey) {
key = aKey;
}
public String getKey() {
return key;
}
public void setKey(String aKey) {
String englishValue = getEnglish();
String frenchValue = getFrench();
String dutchValue = getDutch();
key = aKey;
setEnglish(englishValue);
setFrench(frenchValue);
setDutch(dutchValue);
}
public String getEnglish() {
return getLocalizedForKeyAndLanguage(key, Language.ENGLISH);
}
public void setEnglish(String value) {
setLocalizedForKeyAndLanguage(key, value, Language.ENGLISH);
}
public String getFrench() {
return getLocalizedForKeyAndLanguage(key, Language.FRENCH);
}
public void setFrench(String value) {
setLocalizedForKeyAndLanguage(key, value, Language.FRENCH);
}
public String getDutch() {
return getLocalizedForKeyAndLanguage(key, Language.DUTCH);
}
public void setDutch(String value) {
setLocalizedForKeyAndLanguage(key, value, Language.DUTCH);
}
@Override
public String toString() {
return "(key=" + key + "{en=" + getEnglish() + ";fr=" + getFrench() + ";du=" + getDutch() + "})";
}
}
// This method is really not efficient, but only called in the context of locales editor
// This issue is not really severe.
private Vector<String> buildAllKeys() {
Vector<String> returned = new Vector<String>();
for (Language l : _values.keySet()) {
for (String key : _values.get(l).keySet()) {
if (!returned.contains(key)) {
returned.add(key);
}
}
}
return returned;
}
// This method is really not efficient, but only called in the context of locales editor
// Impact of this issue is not really severe.
public Vector<DynamicEntry> getDynamicEntries() {
if (dynamicEntries == null) {
dynamicEntries = new Vector<DynamicEntry>();
for (String key : buildAllKeys()) {
dynamicEntries.add(new DynamicEntry(key));
}
Collections.sort(dynamicEntries, new Comparator<DynamicEntry>() {
@Override
public int compare(DynamicEntry o1, DynamicEntry o2) {
return Collator.getInstance().compare(o1.key, o2.key);
}
});
}
return dynamicEntries;
}
private DynamicEntry getDynamicEntry(String key) {
if (key == null) {
return null;
}
for (DynamicEntry entry : getDynamicEntries()) {
if (key.equals(entry.key)) {
return entry;
}
}
return null;
}
public void refresh() {
logger.fine("Refresh called on FIBLocalizedDictionary " + Integer.toHexString(hashCode()));
dynamicEntries = null;
setChanged();
notifyObservers();
}
public DynamicEntry addEntry() {
String key = "new_entry";
DynamicEntry newDynamicEntry = new DynamicEntry(key);
dynamicEntries.add(newDynamicEntry);
Collections.sort(dynamicEntries, new Comparator<DynamicEntry>() {
@Override
public int compare(DynamicEntry o1, DynamicEntry o2) {
return Collator.getInstance().compare(o1.key, o2.key);
}
});
return null;
}
public void deleteEntry(DynamicEntry entry) {
for (Language l : Language.availableValues()) {
_values.get(l).remove(entry.key);
FIBLocalizedEntry e = getEntry(l, entry.key);
if (e != null) {
_entries.remove(e);
}
}
refresh();
}
public void beginSearchNewLocalizationEntries() {
isSearchingNewEntries = true;
}
public void endSearchNewLocalizationEntries() {
isSearchingNewEntries = false;
}
@Override
public List<? extends FIBModelObject> getEmbeddedObjects() {
return getEntries();
}
@Override
public boolean registerNewEntry(String key, Language language, String value) {
setLocalizedForKeyAndLanguage(key, value, language);
return true;
}
private LocalizedDelegate parentLocalizedDelegate;
@Override
public LocalizedDelegate getParent() {
return parentLocalizedDelegate;
}
public void setParent(LocalizedDelegate parentLocalizedDelegate) {
this.parentLocalizedDelegate = parentLocalizedDelegate;
}
}