diff --git a/.idea/misc.xml b/.idea/misc.xml
index c6d8fb7..27ef7ce 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,8 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/com/tofvesson/joe/Language.java b/src/com/tofvesson/joe/Language.java
index 3c34bf6..62be0cf 100644
--- a/src/com/tofvesson/joe/Language.java
+++ b/src/com/tofvesson/joe/Language.java
@@ -6,24 +6,50 @@ import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
-@SuppressWarnings({"WeakerAccess", "unused"})
+@SuppressWarnings({"WeakerAccess", "unused", "ConstantConditions", "SameParameterValue"})
public class Language {
- private final String language, languageID;
+ private final String language, languageID, entry;
private Map data = new HashMap<>();
private final File f;
+ private final ZipFile zip;
+
+
+ private Language(ZipFile zip, String entry, String language, String languageID){
+ this.zip = zip;
+ this.entry = entry;
+ this.language = language;
+ this.languageID = languageID;
+ this.f = null;
+ }
+
+ private Language(File f, String language, String languageID){
+ this.f = f;
+ this.language = language;
+ this.languageID = languageID;
+ entry = null;
+ zip = null;
+ }
+
+ private Language(){
+ f = null;
+ language="";
+ languageID="";
+ entry = "";
+ zip = null;
+ }
- 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(f==null && zip==null && (entry==null || (entry!=null && entry.equals("")))) return "";
if(data.containsKey(key) || !f.isFile()) return data.get(key);
try {
- InputStream i = new FileInputStream(f);
+ InputStream i = f!=null?new FileInputStream(f):zip.getInputStream(zip.getEntry(entry));
readLine(i);
String s, s1="";
while(i.available()>0){
@@ -70,6 +96,26 @@ public class Language {
!s.equals("0"))?defaultValue:(s.equalsIgnoreCase("true")||s.equals("1"))&&(!s.equalsIgnoreCase("false")||!s.equals("0"));
}
+ /**
+ * Parses data aggressively from zip.
+ * @param zip Zip file to load language data from.
+ * @param entry Entry in zip file.
+ * @return Language or null.
+ */
+ public static @Nullable Language safeParse(ZipFile zip, String entry){ return safeParse(zip, entry, true); }
+
+ /**
+ * A safe version of {@link #parse(ZipFile, String, boolean)} that will simply return null if given file isn't a valid language file.
+ * @param zip Zip file to load language data from.
+ * @param entry Entry in zip file.
+ * @param aggressiveLoading Whether or not to aggressively load and handle data.
+ * @return Language or null.
+ */
+ public static @Nullable Language safeParse(ZipFile zip, String entry, boolean aggressiveLoading){
+ try{ return parse(zip, entry, aggressiveLoading); }catch(Exception ignored){}
+ return null;
+ }
+
/**
* Parses data aggressively.
* @param f File to read from.
@@ -90,11 +136,38 @@ public class Language {
return null;
}
+ /**
+ * Parses the given zip entry into a usable language very aggressively.
+ * @param zip Zip file to load language data from.
+ * @param entry Entry in zip file.
+ * @return Language.
+ * @throws NotALanguageFileException if Zip data isn't a real zip file or entry.
+ * @throws IOException if data can't be read.
+ * @throws MalformedLanguageException if language file isn't specified correctly.
+ */
+ public static Language parse(ZipFile zip, String entry) throws NotALanguageFileException, IOException, MalformedLanguageException { return parse(zip, entry, true); }
+
+ /**
+ * Parses the given zip entry into a usable language.
+ * @param zip Zip file to load language data from.
+ * @param entry Entry in zip file.
+ * @param aggressiveParsing Whether or not to aggressively load and handle data.
+ * @return Language.
+ * @throws NotALanguageFileException Thrown if file isn't a valid language file.
+ * @throws IOException if data can't be read.
+ * @throws MalformedLanguageException if language file isn't specified correctly.
+ */
+ public static Language parse(ZipFile zip, String entry, boolean aggressiveParsing) throws NotALanguageFileException, IOException, MalformedLanguageException {
+ return parse(zip, entry, null, aggressiveParsing);
+ }
+
/**
* 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.
+ * @throws IOException if data can't be read.
+ * @throws MalformedLanguageException if language file isn't specified correctly.
*/
public static Language parse(File f) throws NotALanguageFileException, IOException, MalformedLanguageException {
return parse(f, true);
@@ -106,17 +179,34 @@ public class Language {
* @param aggressiveParsing Whether or not to aggressively load and handle data.
* @return Language.
* @throws NotALanguageFileException Thrown if file isn't a valid language file.
+ * @throws IOException if data can't be read.
+ * @throws MalformedLanguageException if language file isn't specified correctly.
*/
- public static Language parse(File f, boolean aggressiveParsing) throws NotALanguageFileException, MalformedLanguageException, IOException {
- String s;
-
-
+ public static Language parse(File f, boolean aggressiveParsing) throws NotALanguageFileException, IOException, MalformedLanguageException {
// Is file existent?
if(!f.isFile()) throw new FileNotFoundException("File "+f.getAbsolutePath()+" isn't a file!");
+ return parse(null, "", f, aggressiveParsing);
+ }
+ /**
+ * Parses the given file or zip entry data into a usable language.
+ * @param zip Zip file to load language data from.
+ * @param entry Entry in zip file.
+ * @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.
+ * @throws IOException if data can't be read.
+ * @throws MalformedLanguageException if language file isn't specified correctly.
+ */
+ private static Language parse(ZipFile zip, String entry, File f, boolean aggressiveParsing) throws NotALanguageFileException, MalformedLanguageException, IOException {
+ String s;
+ ZipEntry z = zip==null?null:zip.getEntry(entry);
+ if(z==null && zip!=null) throw new NotALanguageFileException("File "+zip.getName()+":/"+entry+" isn't a file!");
+
+ InputStream i = zip==null?new FileInputStream(f):zip.getInputStream(zip.getEntry(entry));
// Does file meet preliminary requirements?
- InputStream i = new FileInputStream(f);
s = ignoreSpaces(readLine(i));
i.close();
for(int j=0; j=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('.')));
+ Language l = zip==null ? new Language(f, s.substring(start, end), f.getName().substring(0, f.getName().lastIndexOf('.')))
+ : new Language(zip, entry, s.substring(start, end), f.getName().substring(0, f.getName().lastIndexOf('.')));
// Check language integrity
ArrayList keys = new ArrayList<>();
- i = new FileInputStream(f);
+ i = zip==null?new FileInputStream(f):zip.getInputStream(zip.getEntry(entry));
String subVerify;
boolean firstLine = true;
char read;
@@ -161,7 +252,7 @@ public class Language {
if(subVerify.length()==0 || subVerify.toCharArray().length==0 || subVerify.toCharArray()[0]=='\n') continue;
++lineCount;
if(!isValidKVPair(subVerify)) throw new MalformedLanguageException("Error found at line "+lineCount
- +" of "+f.getAbsolutePath()+". Invalid key-value pair detected! Note that ':' in the keys or values must be escaped with '\'");
+ +" 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!");
diff --git a/src/com/tofvesson/joe/Localization.java b/src/com/tofvesson/joe/Localization.java
index 6f42812..be496cb 100644
--- a/src/com/tofvesson/joe/Localization.java
+++ b/src/com/tofvesson/joe/Localization.java
@@ -3,8 +3,11 @@ package com.tofvesson.joe;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.List;
import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
@SuppressWarnings({"WeakerAccess", "unused"})
public class Localization {
@@ -12,6 +15,32 @@ public class Localization {
private Language defaultLang;
private List all = new ArrayList<>();
+ public Localization(ZipFile zip, String folder, String regexNamingPattern){ this(zip, folder, regexNamingPattern, true); }
+ public Localization(ZipFile zip, String folder){ this(zip, folder, true); }
+ public Localization(ZipFile zip, String folder, boolean aggressiveLoading){ this(zip, folder, "(.*)", aggressiveLoading); }
+ public Localization(ZipFile zip, String folder, String regexNamingPattern, boolean aggressiveLoading){
+ Pattern p = Pattern.compile(regexNamingPattern);
+ ArrayList files = new ArrayList<>();
+ Enumeration extends ZipEntry> e = zip.entries();
+ ZipEntry tmp;
+ while(e.hasMoreElements())
+ if((tmp=e.nextElement()).getName().startsWith(folder) && p.matcher(tmp.getName()).find())
+ files.add(tmp.getName());
+ if(files.size()==0){
+ fixFail();
+ return;
+ }
+
+ try {
+ for (String s : files) {
+ if(defaultLang==null){
+ defaultLang = Language.parse(zip, s, aggressiveLoading);
+ all.add(defaultLang);
+ }else all.add(Language.parse(zip, s, aggressiveLoading));
+ }
+ }catch(Exception ignored){}
+
+ }
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); }