package neembuu.uploader.translation; import neembuu.rus.InterfaceInstanceCreator; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.lang.reflect.Proxy; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import neembuu.uploader.api.AppLocationProvider; //import neembuu.uploader.settings.SettingsManager; import neembuu.uploader.utils.NULogger; /** * * @author Shashank Tulsyan */ public final class Translation { //private final Properties properties; //private final String language; //guarded by this class private static TranslationValues singleton = null; private static final TranslationValues defaultprovider = InterfaceInstanceCreator.getDefault(TranslationValues.class); //private static AppLocationProvider appLocationProvider = null; private static LanguageChangedCallback lcc; private static Path /*home,*/updatedTranslationsLocation,defaultTranslationsLocation; public static final void init(AppLocationProvider alp, LanguageChangedCallback lcc,Path home){ if(updatedTranslationsLocation!=null){ throw new IllegalStateException("Already initialized"); } if(Translation.lcc!=null){ throw new IllegalStateException("Already initialized"); } //Translation.appLocationProvider = alp; Translation.lcc = lcc; //Translation.home = home; updatedTranslationsLocation = home.resolve("external").resolve("translations"); defaultTranslationsLocation = alp.getPath().toPath().resolve("translations"); } /** * * @return a translation provider based on default locale. If none exist, get Translation for English */ public static synchronized TranslationValues T() { if (singleton == null) { return defaultprovider; } return singleton; } public static synchronized String T(String code) { TranslationValues t = T(); InterfaceInstanceCreator tInstance = (InterfaceInstanceCreator)Proxy.getInvocationHandler(t); return tInstance.getByName(code); } /** * * @return Translation with English language as default */ public static synchronized TranslationValues getDefaultTranslation() { return defaultprovider; } public static synchronized String getDefaultTranslation(String code){ TranslationValues t = defaultprovider; InterfaceInstanceCreator tInstance = (InterfaceInstanceCreator)Proxy.getInvocationHandler(t); return tInstance.getByName(code); } /** * * @return language currently in use */ public final String getLanguage() { return T().languageLocale(); } /**This is the method used to initialize Translation and also to change language. * It also updates the GUI of NeembuuUploader and Table automatically. * @param languagecode locale * @throws SecurityException The program is designed to allow * changes from only NeembuuUploader.class and Translation.class . * This is to prevent, malicious behavior. */ public static synchronized void changeLanguage(String languagecode) { // getStackTrace()[0] will be getStackTrace() // getStackTrace()[1] will be changeLanguage() // getStackTrace()[2] will be the calling class which should be one of the three allowed classes. String name = Thread.currentThread().getStackTrace()[2].getClassName(); // takes around 228.3 microsec //name = sun.reflect.Reflection.getCallerClass(2).getName(); // takes around 40 microsecs*/ if (!name.equals("neembuu.uploader.NeembuuUploader") && !name.equals("neembuu.uploader.Main") && !name.equals(Translation.class.getName()) && !name.equals("neembuu.uploader.settings.SettingsManager")) { /*throw new SecurityException(name + " does not have rights to call this function");*/ } TranslationValues res = locateTranslationFile(languagecode); if(res==null){ NULogger.getLogger().log(Level.INFO, "{0}Could not change language", languagecode); return; } singleton = res; NULogger.getLogger().log(Level.INFO, "{0}Language Changed", Translation.class.getName()); //Update GUI on NU lcc.updateGUI(); //NeembuuUploader.getInstance().languageChanged_UpdateGUI(); } private static TranslationValues locateTranslationFile(String languagecode){ File ret = locateTranslationFile(languagecode, updatedTranslationsLocation); if(ret==null){ ret = locateTranslationFile(languagecode, defaultTranslationsLocation); }if(ret==null)return null; if(ret.exists()){ //Properties p = new Properties(); HashMap<String,String> p = new HashMap<>(); //try (FileInputStream in = new FileInputStream(ret)) { try{ List<String> lines = Files.readAllLines(ret.toPath(), Charset.forName("UTF-8")); for (String l : lines) { int i = l.indexOf('='); String val = l.substring(i+1,l.length()).trim(); String nam = l.substring(0,i).trim(); p.put(nam, val); } //p.load(in); } catch (IOException ex) { Logger.getLogger(Translation.class.getName()).log(Level.SEVERE, null, ex); return null; } return InterfaceInstanceCreator.create(p,TranslationValues.class); } return null; } private static File locateTranslationFile(String languagecode,Path useLocation){ final FilenameFilter ff = new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.toLowerCase().endsWith(".translation"); }}; File[]trans=useLocation.toFile().listFiles(ff); for (File file : trans) { try{ String l = file.getName(); String name = l.substring(0,l.indexOf('.')); l = l.substring(l.indexOf('.')+1); l = l.substring(0,l.indexOf('.')); if(l.equalsIgnoreCase(languagecode)){ return file; } }catch(Exception a){ Logger.getLogger(Translation.class.getName()).log( Level.SEVERE, "Could not handle language file "+file.getName(), a); } } return null; } }