Code finalized

This commit is contained in:
Gabriel Tofvesson 2016-11-15 19:14:45 +01:00
parent 15027ce547
commit c313a8fab8
8 changed files with 197 additions and 84 deletions

View File

@ -1,13 +0,0 @@
import com.tofvesson.joe.Language;
import java.io.File;
public class Test {
public static void main(String args[]){
try{
Language test = Language.parse(new File(Test.class.getResource("/Test.txt").getFile()));
System.out.println("Language: "+test.getLanguage());
System.out.println("Identifier: "+test.getLanguageIdentifier());
}catch(Exception e){ e.printStackTrace();}
}
}

View File

@ -1,2 +0,0 @@
Language: Test
asdf

View File

@ -1,14 +0,0 @@
package com.tofvesson.joe;
import java.io.File;
import java.util.HashMap;
public class Dataset<T> {
HashMap<String, T> data = new HashMap<>();
private final Type type;
public Dataset(Type type, File input){
this.type = type;
}
}

View File

@ -4,35 +4,97 @@ import com.sun.istack.internal.Nullable;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings({"WeakerAccess", "unused"})
public class Language {
private final String language, languageID;
private Map<String, String> data = new HashMap<>();
private final File f;
private Language(String language, String languageID){ this.language = language; this.languageID = languageID; }
private Language(File f, String language, String languageID){ this.f = f; this.language = language; this.languageID = languageID; }
private Language(){ f = null; language=""; languageID=""; }
public String getLanguage(){ return language; }
public String getLanguageIdentifier(){ return languageID; }
public String get(String key) {
if(f==null) return "";
if(data.containsKey(key) || !f.isFile()) return data.get(key);
try {
InputStream i = new FileInputStream(f);
readLine(i);
String s, s1;
while(!(s1=getKey(s=readLine(i))).equals(key))
if(i.available()<=0) break;
if(s1.equals(key)){
data.put(s1, s=getValue(s));
return s;
}
} catch (IOException ignored) {}
return null;
}
public int getInt(String key){
String s = get(key);
if(s==null) return 0;
try{
return Integer.parseInt(s);
}catch(Exception e){ return 0; }
}
public double getDouble(String key){
String s = get(key);
if(s==null) return 0;
try{
return Double.parseDouble(s);
}catch(Exception e){ return 0; }
}
public boolean getBoolean(String key, boolean defaultValue){
String s;
return (s = get(key))==null||(!s.equalsIgnoreCase("true")&&!s.equals("1")&&!s.equalsIgnoreCase("false")&&
!s.equals("0"))?defaultValue:(s.equalsIgnoreCase("true")||s.equals("1"))&&(!s.equalsIgnoreCase("false")||!s.equals("0"));
}
/**
* A safe version of {@link #parse(File)} that will simply return <b>null</b> if given file isn't a valid language file.
* Parses data aggressively.
* @param f File to read from.
* @return Language or null.
*/
public static @Nullable Language safeParse(File f){
try{ return parse(f); }catch(Exception ignored){}
return safeParse(f, true);
}
/**
* A safe version of {@link #parse(File, boolean)} that will simply return <b>null</b> if given file isn't a valid language file.
* @param f File to read from.
* @param aggressiveParsing Whether or not to aggressively load and handle data.
* @return Language or null.
*/
public static @Nullable Language safeParse(File f, boolean aggressiveParsing){
try{ return parse(f, aggressiveParsing); }catch(Exception ignored){}
return null;
}
/**
* Parses the given file into a usable language very aggressively.
* @param f File to parse.
* @return Language.
* @throws NotALanguageFileException Thrown if file isn't a valid language file.
*/
public static Language parse(File f) throws NotALanguageFileException, IOException, MalformedLanguageException {
return parse(f, true);
}
/**
* Parses the given file into a usable language.
* @param f File to parse.
* @param aggressiveParsing Whether or not to aggressively load and handle data.
* @return Language.
* @throws NotALanguageFileException Thrown if file isn't a valid language file.
*/
public static Language parse(File f) throws NotALanguageFileException, MalformedLanguageException, IOException {
String s="";
public static Language parse(File f, boolean aggressiveParsing) throws NotALanguageFileException, MalformedLanguageException, IOException {
String s;
// Is file existent?
@ -41,7 +103,6 @@ public class Language {
// Does file meet preliminary requirements?
InputStream i = new FileInputStream(f);
int c;
s = ignoreSpaces(readLine(i));
i.close();
for(int j=0; j<s.length(); ++j)
@ -56,6 +117,8 @@ public class Language {
if(start==-1 || end==-1 || start>=end) throw new NotALanguageFileException("Malformed language name definition: \""+s+"\"");
Language l = new Language(f, s.substring(start, end), f.getName().substring(0, f.getName().lastIndexOf('.')));
// Check language integrity
ArrayList<String> keys = new ArrayList<>();
i = new FileInputStream(f);
@ -65,20 +128,24 @@ public class Language {
int lineCount = 1;
while(i.available()>0){
read = (char) i.read();
if(firstLine && read=='\n'){
firstLine=false;
if(read==10) {
if (firstLine) firstLine = false;
continue;
}
subVerify = read+readLine(i);
if(read==' ') subVerify = "";
else subVerify = ""+read;
subVerify += truncateLeadingSpaces(readLine(i));
++lineCount;
if(subVerify.toCharArray().length==0) continue;
if(!isValidKVPair(subVerify)) throw new MalformedLanguageException("Error found at line "+lineCount
+" : \""+subVerify+"\"\nInvalid key-value pair detected! Note that ':' in the keys or values must be escaped with '\\'");
String s1 = getKey(truncateLeadingSpaces(subVerify));
+" of "+f.getAbsolutePath()+". Invalid key-value pair detected! Note that ':' in the keys or values must be escaped with '\'");
String s1 = getKey(subVerify);
if(keys.contains(s1)) throw new MalformedLanguageException("Error found at line "+lineCount+" : "
+subVerify+"\nDuplicate key detected!");
keys.add(getKey(truncateLeadingSpaces(subVerify)));
keys.add(s1);
if(aggressiveParsing) l.data.put(s1, getValue(subVerify));
}
return new Language(s.substring(start, end), f.getName().substring(0, f.getName().lastIndexOf('.')));
return l;
}
private static String ignoreSpaces(String s){
@ -90,29 +157,15 @@ public class Language {
private static String truncateLeadingSpaces(String s){
char[] str = s.toCharArray();
for(int i = 0; i<str.length; ++i) if(str[i]!=' ' && str[i]!='\t') return s.substring(i);
return s;
return "";
}
private static String readLine(InputStream i){
String s = "";
char j;
try{ while(i.available()>0 && (j=(char)i.read())!='\n') s+=j; }catch(IOException ignored){}
try{ while(i.available()>0 && (j=(char)i.read())!='\n' && j!=13) s+=j; }catch(IOException ignored){}
return s;
}
private static int amountOf(char toFind, String in){
char[] c = in.toCharArray();
int ctr = 0;
for(char c1 : c) if(c1==toFind) ++ctr;
return ctr;
}
private static Type getTypeForString(String name){
for(Type t : Type.values())
if(name.equalsIgnoreCase(t.name())) return t;
return null;
}
private static boolean isValidKVPair(String data){
boolean colonFound = false;
char[] str = truncateLeadingSpaces(data).toCharArray();
@ -140,4 +193,17 @@ public class Language {
}
return data;
}
private static String getValue(String data){
char[] str = truncateLeadingSpaces(data).toCharArray();
char prev = 0;
for(int i = str.length-1; i>0; --i) {
if (i != str.length-1){
if(str[i]!='\\' && prev==':')
return data.substring(i+2, str.length);
}
prev = str[i];
}
return data;
}
}

View File

@ -1,5 +1,100 @@
package com.tofvesson.joe;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
@SuppressWarnings({"WeakerAccess", "unused"})
public class Localization {
private Language defaultLang;
private List<Language> all = new ArrayList<>();
public Localization(File folder, String regexNamingPattern){ this(folder, regexNamingPattern, true); }
public Localization(File folder){ this(folder, true); }
public Localization(File folder, boolean aggressiveLoading){ this(folder, "(.*)", aggressiveLoading); }
public Localization(File folder, String regexNamingPattern, boolean aggressiveLoading){
if(folder==null || !folder.isDirectory()) throw new RuntimeException("Folder argument passed isn't a directory!");
String[] s;
if((s=folder.list())==null || s.length==0){
fixFail();
return;
}
try {
File[] fs = folder.listFiles();
if(fs==null){
fixFail();
return;
}
for (File f : fs) {
if (Pattern.matches(regexNamingPattern, f.getName())){
if(defaultLang==null){
defaultLang = Language.parse(f, aggressiveLoading);
all.add(defaultLang);
}else all.add(Language.parse(f, aggressiveLoading));
}
}
}catch(Exception ignored){}
if(defaultLang==null) fixFail();
}
private void fixFail(){
try{
Constructor<Language> c = Language.class.getDeclaredConstructor();
c.setAccessible(true);
defaultLang=c.newInstance();
all.add(defaultLang);
}catch(Exception ignored){}
}
public String get(String language, String key){
for(Language l : all)
if(l.getLanguage().equals(language))
return l.get(key);
return defaultLang.get(key);
}
public String get(String key){ return defaultLang.get(key); }
public int getInt(String language, String key){
for(Language l : all)
if(l.getLanguage().equals(language))
return l.getInt(key);
return defaultLang.getInt(key);
}
public int getInt(String key){ return defaultLang.getInt(key); }
public double getDouble(String language, String key){
for(Language l : all)
if(l.getLanguage().equals(language))
return l.getDouble(key);
return defaultLang.getDouble(key);
}
public double getDouble(String key){ return defaultLang.getDouble(key); }
public boolean getBoolean(String language, String key, boolean defaultValue){
for(Language l : all)
if(l.getLanguage().equals(language))
return l.getBoolean(key, defaultValue);
return defaultLang.getBoolean(key, defaultValue);
}
public boolean getBoolean(String key, boolean defaultValue){ return defaultLang.getBoolean(key, defaultValue); }
public Language[] getLanguages(){ return all.toArray(new Language[all.size()]); }
public String[] getLanguageNames(){
String[] s = new String[all.size()];
for(int i = 0; i<s.length; ++i) s[i]=all.get(i).getLanguage();
return s;
}
public Language getDefaultLanguage(){ return defaultLang; }
public Language setDefaultLanguage(Language newLang){ Language l = defaultLang; defaultLang = newLang; return l; }
}

View File

@ -1,23 +1,14 @@
package com.tofvesson.joe;
@SuppressWarnings({"unused", "WeakerAccess"})
public class MalformedLanguageException extends Exception {
public MalformedLanguageException() {
super();
}
public MalformedLanguageException() { super(); }
public MalformedLanguageException(String message) {
super(message);
}
public MalformedLanguageException(String message, Throwable cause) {
super(message, cause);
}
public MalformedLanguageException(Throwable cause) {
super(cause);
}
public MalformedLanguageException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public MalformedLanguageException(Throwable cause) { super(cause); }
public MalformedLanguageException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); }
}

View File

@ -1,15 +1,10 @@
package com.tofvesson.joe;
@SuppressWarnings({"unused", "WeakerAccess"})
public class NotALanguageFileException extends Exception {
public NotALanguageFileException() { super(); }
public NotALanguageFileException(String message) { super(message); }
public NotALanguageFileException(String message, Throwable cause) { super(message, cause); }
public NotALanguageFileException(Throwable cause) { super(cause); }
public NotALanguageFileException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public NotALanguageFileException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); }
}

View File

@ -1,5 +0,0 @@
package com.tofvesson.joe;
public enum Type {
Text, Number, Boolean
}