com.optimaize.langdetect.profiles.LanguageProfileReader Maven / Gradle / Ivy
package com.optimaize.langdetect.profiles;
import com.optimaize.langdetect.frma.LangProfileReader;
import com.optimaize.langdetect.i18n.LdLocale;
import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Reads {@link LanguageProfile}s.
*
* @author Fabian Kessler
*/
public class LanguageProfileReader {
private static final LangProfileReader internalReader = new LangProfileReader();
private static final String PROFILES_DIR = "languages";
/**
* Reads a {@link LanguageProfile} from a File in UTF-8.
*/
public LanguageProfile read(File profileFile) throws IOException {
return OldLangProfileConverter.convert(internalReader.read(profileFile));
}
/**
* Reads a {@link LanguageProfile} from an InputStream in UTF-8.
*/
public LanguageProfile read(InputStream inputStream) throws IOException {
return OldLangProfileConverter.convert(internalReader.read(inputStream));
}
/**
* Load profiles from the classpath in a specific directory.
*
* This is usually used to load built-in profiles, shipped with the jar.
*
* @param classLoader the ClassLoader to load the profiles from. Use {@code MyClass.class.getClassLoader()}
* @param profileDirectory profile directory path inside the classpath. The default profiles are in "languages".
* @param profileFileNames for example ["en", "fr", "de"].
*/
public List read(ClassLoader classLoader, String profileDirectory, Collection profileFileNames) throws IOException {
List loaded = new ArrayList<>(profileFileNames.size());
for (String profileFileName : profileFileNames) {
String path = makePathForClassLoader(profileDirectory, profileFileName);
try (InputStream in = classLoader.getResourceAsStream(path)) {
if (in == null) {
throw new IOException("No language file available named "+profileFileName+" at " + path + "!");
}
loaded.add( read(in) );
}
}
return loaded;
}
private String makePathForClassLoader(String profileDirectory, String fileName) {
//WITHOUT slash before the profileDirectory when using the classloader!
return profileDirectory + '/' + fileName;
}
/**
* Same as {@link #read(ClassLoader, String, java.util.Collection)} using the class loader of this class.
*/
public List read(String profileDirectory, Collection profileFileNames) throws IOException {
return read(LanguageProfileReader.class.getClassLoader(), profileDirectory, profileFileNames);
}
/**
* Same as {@link #read(ClassLoader, String, java.util.Collection)} using the class loader of this class,
* and the default profiles directory of this library.
*/
public List read(Collection profileFileNames) throws IOException {
return read(LanguageProfileReader.class.getClassLoader(), PROFILES_DIR, profileFileNames);
}
@NotNull
public LanguageProfile readBuiltIn(@NotNull LdLocale locale) throws IOException {
String filename = makeProfileFileName(locale);
String path = makePathForClassLoader(PROFILES_DIR, filename);
try (InputStream in = LanguageProfileReader.class.getClassLoader().getResourceAsStream(path)) {
if (in == null) {
throw new IOException("No language file available named "+filename+" at " + path + "!");
}
return read(in);
}
}
@NotNull
private String makeProfileFileName(@NotNull LdLocale locale) {
return locale.toString();
}
@NotNull
public List readBuiltIn(@NotNull Collection languages) throws IOException {
List profileNames = new ArrayList<>();
for (LdLocale locale : languages) {
profileNames.add(makeProfileFileName(locale));
}
return read(LanguageProfileReader.class.getClassLoader(), PROFILES_DIR, profileNames);
}
/**
* @deprecated renamed to readAllBuiltIn()
*/
public List readAll() throws IOException {
return readAllBuiltIn();
}
/**
* Reads all built-in language profiles from the "languages" folder (shipped with the jar).
*/
public List readAllBuiltIn() throws IOException {
List loaded = new ArrayList<>();
for (LdLocale locale : BuiltInLanguages.getLanguages()) {
loaded.add(readBuiltIn(locale));
}
return loaded;
}
/**
* Loads all profiles from the specified directory.
*
* Do not use this method for files distributed within a jar.
*
* @param path profile directory path
* @return empty if there is no language file in it.
*/
public List readAll(File path) throws IOException {
if (!path.exists()) {
throw new IOException("No such folder: "+path);
}
if (!path.canRead()) {
throw new IOException("Folder not readable: "+path);
}
File[] listFiles = path.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return looksLikeLanguageProfileFile(pathname);
}
});
if (listFiles == null) {
throw new IOException("Failed reading from folder: " + path);
}
List profiles = new ArrayList<>(listFiles.length);
for (File file: listFiles) {
if (!looksLikeLanguageProfileFile(file)) {
continue;
}
profiles.add(read(file));
}
return profiles;
}
private boolean looksLikeLanguageProfileFile(File file) {
if (!file.isFile()) {
return false;
}
return looksLikeLanguageProfileName(file.getName());
}
private boolean looksLikeLanguageProfileName(String fileName) {
if (fileName.contains(".")) {
return false;
}
try {
LdLocale.fromString(fileName);
return true;
} catch (Exception e) {
return false;
}
}
}