Added localization classes and the start of the localization process.

This commit is contained in:
Krazy
2014-08-08 01:05:03 +00:00
parent 1ca0428ae9
commit c26de845e1
9 changed files with 181 additions and 48 deletions

View File

@@ -19,6 +19,7 @@ package forge;
import forge.card.CardRules;
import forge.util.FileUtil;
import forge.util.Localizer;
import forge.util.ThreadUtil;
import org.apache.commons.lang3.time.StopWatch;
@@ -71,21 +72,6 @@ public class CardStorageReader {
private final Observer observer;
// 8/18/11 10:56 PM
/**
* <p>
* Constructor for CardReader.
* </p>
*
* @param theCardsFolder
* indicates location of the cardsFolder
* @param useZip
* if true, attempts to load cards from a zip file, if one
* exists.
*/
public CardStorageReader(String cardDataDir, CardStorageReader.ProgressObserver progressObserver, Observer observer) {
this.progressObserver = progressObserver != null ? progressObserver : CardStorageReader.ProgressObserver.emptyObserver;
this.cardsfolder = new File(cardDataDir);
@@ -114,10 +100,10 @@ public class CardStorageReader {
} // CardReader()
private final List<CardRules> loadCardsInRange(final List<File> files, int from, int to) {
private List<CardRules> loadCardsInRange(final List<File> files, int from, int to) {
CardRules.Reader rulesReader = new CardRules.Reader();
List<CardRules> result = new ArrayList<CardRules>();
List<CardRules> result = new ArrayList<>();
for(int i = from; i < to; i++) {
File cardTxtFile = files.get(i);
result.add(this.loadCard(rulesReader, cardTxtFile));
@@ -125,10 +111,10 @@ public class CardStorageReader {
return result;
}
private final List<CardRules> loadCardsInRangeFromZip(final List<ZipEntry> files, int from, int to) {
private List<CardRules> loadCardsInRangeFromZip(final List<ZipEntry> files, int from, int to) {
CardRules.Reader rulesReader = new CardRules.Reader();
List<CardRules> result = new ArrayList<CardRules>();
List<CardRules> result = new ArrayList<>();
for(int i = from; i < to; i++) {
ZipEntry ze = files.get(i);
// if (ze.getName().endsWith(CardStorageReader.CARD_FILE_DOT_EXTENSION)) // already filtered!
@@ -146,13 +132,16 @@ public class CardStorageReader {
* @return the Card or null if it was not found.
*/
public final Iterable<CardRules> loadCards() {
progressObserver.setOperationName("Loading cards, examining folder", true);
Localizer localizer = Localizer.getInstance();
progressObserver.setOperationName(localizer.getMessage("splash.loading.examining-cards"), true);
// Iterate through txt files or zip archive.
// Report relevant numbers to progress monitor model.
Set<CardRules> result = new TreeSet<CardRules>(new Comparator<CardRules>() {
Set<CardRules> result = new TreeSet<>(new Comparator<CardRules>() {
@Override
public int compare(CardRules o1, CardRules o2) {
return String.CASE_INSENSITIVE_ORDER.compare(o1.getName(), o2.getName());
@@ -166,7 +155,7 @@ public class CardStorageReader {
fileParts = allFiles.size() / 100; // to avoid creation of many threads for a dozen of files
final CountDownLatch cdlFiles = new CountDownLatch(fileParts);
List<Callable<List<CardRules>>> taskFiles = makeTaskListForFiles(allFiles, cdlFiles);
progressObserver.setOperationName("Loading cards from folders", true);
progressObserver.setOperationName(localizer.getMessage("splash.loading.cards-folders"), true);
progressObserver.report(0, taskFiles.size());
StopWatch sw = new StopWatch();
sw.start();
@@ -178,10 +167,10 @@ public class CardStorageReader {
if( this.zip != null ) {
final CountDownLatch cdlZip = new CountDownLatch(NUMBER_OF_PARTS);
List<Callable<List<CardRules>>> taskZip = new ArrayList<>();
List<Callable<List<CardRules>>> taskZip;
ZipEntry entry;
List<ZipEntry> entries = new ArrayList<ZipEntry>();
List<ZipEntry> entries = new ArrayList<>();
// zipEnum was initialized in the constructor.
Enumeration<? extends ZipEntry> zipEnum = this.zip.entries();
while (zipEnum.hasMoreElements()) {
@@ -192,7 +181,7 @@ public class CardStorageReader {
}
taskZip = makeTaskListForZip(entries, cdlZip);
progressObserver.setOperationName("Loading cards from archive", true);
progressObserver.setOperationName(localizer.getMessage("splash.loading.cards-archive"), true);
progressObserver.report(0, taskZip.size());
StopWatch sw = new StopWatch();
sw.start();
@@ -220,9 +209,7 @@ public class CardStorageReader {
result.addAll(c.call());
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} catch (Exception e) { // this clause comes from non-threaded branch
throw new RuntimeException(e);
@@ -233,7 +220,7 @@ public class CardStorageReader {
int totalFiles = entries.size();
final int maxParts = (int) cdl.getCount();
int filesPerPart = totalFiles / maxParts;
final List<Callable<List<CardRules>>> tasks = new ArrayList<Callable<List<CardRules>>>();
final List<Callable<List<CardRules>>> tasks = new ArrayList<>();
for (int iPart = 0; iPart < maxParts; iPart++) {
final int from = iPart * filesPerPart;
final int till = iPart == maxParts - 1 ? totalFiles : from + filesPerPart;
@@ -254,7 +241,7 @@ public class CardStorageReader {
int totalFiles = allFiles.size();
final int maxParts = (int) cdl.getCount();
int filesPerPart = totalFiles / maxParts;
final List<Callable<List<CardRules>>> tasks = new ArrayList<Callable<List<CardRules>>>();
final List<Callable<List<CardRules>>> tasks = new ArrayList<>();
for (int iPart = 0; iPart < maxParts; iPart++) {
final int from = iPart * filesPerPart;
final int till = iPart == maxParts - 1 ? totalFiles : from + filesPerPart;
@@ -297,10 +284,7 @@ public class CardStorageReader {
/**
* Load a card from a txt file.
*
* @param pathToTxtFile
* the full or relative path to the file to load
*
*
* @return a new Card instance
*/
protected final CardRules loadCard(final CardRules.Reader reader, final File file) {
@@ -317,7 +301,8 @@ public class CardStorageReader {
throw new RuntimeException("CardReader : run error -- file not found: " + file.getPath(), ex);
} finally {
try {
fileInputStream.close();
assert fileInputStream != null;
fileInputStream.close();
} catch (final IOException ignored) {
// 11:08
// PM
@@ -338,9 +323,8 @@ public class CardStorageReader {
try {
zipInputStream = this.zip.getInputStream(entry);
rulesReader.reset();
CardRules rules = rulesReader.readCard(readScript(zipInputStream));
return rules;
return rulesReader.readCard(readScript(zipInputStream));
} catch (final IOException exn) {
throw new RuntimeException(exn);
// PM

View File

@@ -0,0 +1,5 @@
package forge.util;
public interface LocalizationChangeObserver {
public void localizationChanged();
}

View File

@@ -0,0 +1,122 @@
package forge.util;
import com.ibm.icu.text.MessageFormat;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
public class Localizer {
private static Localizer instance;
private List<LocalizationChangeObserver> observers = new ArrayList<>();
private Locale locale;
private ResourceBundle resourceBundle;
public static Localizer getInstance() {
if (instance == null) {
synchronized (Localizer.class) {
instance = new Localizer();
}
}
return instance;
}
private Localizer() {
}
public void initialize(String localeID, String languagesDirectory) {
setLanguage(localeID, languagesDirectory);
}
public String getMessage(final String key, final Object... messageArguments) {
MessageFormat formatter = null;
try {
formatter = new MessageFormat(resourceBundle.getString(key.toLowerCase()), locale);
} catch (final IllegalArgumentException | MissingResourceException e) {
e.printStackTrace();
}
if (formatter == null) {
return "INVALID PROPERTY: " + key;
}
formatter.setLocale(locale);
String formattedMessage = "CHAR ENCODING ERROR";
try {
//Support non-English-standard characters
formattedMessage = new String(formatter.format(messageArguments).getBytes("ISO-8859-1"), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
}
return formattedMessage;
}
public void setLanguage(final String languageRegionID, final String languagesDirectory) {
String[] splitLocale = languageRegionID.split("-");
Locale oldLocale = locale;
locale = new Locale(splitLocale[0], splitLocale[1]);
//Don't reload the language if nothing changed
if (oldLocale == null || !oldLocale.equals(locale)) {
File file = new File(languagesDirectory);
URL[] urls = null;
try {
urls = new URL[] { file.toURI().toURL() };
} catch (MalformedURLException e) {
e.printStackTrace();
}
ClassLoader loader = new URLClassLoader(urls);
try {
resourceBundle = ResourceBundle.getBundle(languageRegionID, new Locale(splitLocale[0], splitLocale[1]), loader);
} catch (NullPointerException | MissingResourceException e) {
//If the language can't be loaded, default to US English
resourceBundle = ResourceBundle.getBundle("en-US", new Locale("en", "US"), loader);
e.printStackTrace();
}
System.out.println("Language '" + resourceBundle.getBaseBundleName() + "' loaded successfully.");
notifyObservers();
}
}
public List<Langauge> getLanguages() {
//TODO List all languages by getting their files
return null;
}
public void registerObserver(LocalizationChangeObserver observer) {
observers.add(observer);
}
private void notifyObservers() {
for (LocalizationChangeObserver observer : observers) {
observer.localizationChanged();
}
}
public static class Langauge {
public String languageName;
public String langaugeID;
}
}