com.force.i18n.I18nJavaUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grammaticus Show documentation
Show all versions of grammaticus Show documentation
Localization Framework that allows grammatically correct renaming of nouns
/*
* Copyright (c) 2017, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
package com.force.i18n;
import java.io.File;
import java.io.IOException;
import java.net.*;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import com.force.i18n.commons.text.TextUtil;
/**
* A set of utilities used throughout the Grammaticus project.
*
* This should disappear eventually.
* @author stamm
*/
public class I18nJavaUtil {
// For production systems, this should be fine.
// TODO: Use a jar properties file to initialize this.
private static Level LOG_LEVEL = Level.FINE;
private static File CACHE_BASE_DIR = new File(".");
/**
* @return the log level to use for internal operations. The intention is to allow
* different behaviors on production vs development; in development it will throw
* exceptions, on production it will produce log warnings but still function.
* If you set this to more severe than Level.CONFIG, it will have the production behavior.
*/
public static Level getLogLevel() {
return LOG_LEVEL;
}
/**
* Set the log level to use for internal operations.
* @param level the level to set
*/
public static void setLogLevel(Level level) {
LOG_LEVEL = level;
}
/**
* @return whether to throw exceptions for invalid labels instead of coping.
* Return true if the logLevel is < Level.Config
*/
public static boolean isDebugging() {
return LOG_LEVEL.intValue() < Level.CONFIG.intValue();
}
/**
* Given a file (possibly a directory) return the last mod of the file or any recursive children files
* @param includeSubDirs if false then only look in this directory itself, not recursive ones
* @param dir the directory to test
* @return the last modified file in the directory
*/
public static long dirLastModified(File dir, boolean includeSubDirs) {
return dirLastModified(dir, includeSubDirs, false);
}
/**
* Given a file (possibly a directory) return the last mod of the file or any recursive children files
* @param includeSubDirs if false then only look in this directory itself, not recursive ones
* @param dir the directory to test
* @param checkDirectoryTimestampAsWell checks the directory's modification time itself.
* @return the last modified file in the directory
*/
public static long dirLastModified(File dir, boolean includeSubDirs, boolean checkDirectoryTimestampAsWell) {
long lastModified = checkDirectoryTimestampAsWell ? dir.lastModified() : -1;
File[] listOfFiles = dir.listFiles();
if (listOfFiles != null) { // listFiles is null if directory doesn't exist (i.e. not translated)
for (File child : listOfFiles) {
long childLastMod;
if (child.isDirectory()) {
if (!includeSubDirs)
continue;
childLastMod = dirLastModified(child, includeSubDirs, checkDirectoryTimestampAsWell);
} else {
childLastMod = child.lastModified();
}
if (childLastMod > lastModified)
lastModified = childLastMod;
}
}
return lastModified;
}
/**
* @param key the java-style property that is being loaded
* @return the properties for this object
*/
public static final String getProperty(String key) {
ResourceBundle defaultProps = getDefaultProperties();
try {
ResourceBundle overrideProps = getOverrideProperties();
if (overrideProps != null && overrideProps.containsKey(key)) {
return overrideProps.getString(key);
}
} catch (MissingResourceException ex) {
// IGNORE
}
return defaultProps.getString(key);
}
static final ResourceBundle getDefaultProperties() {
return ResourceBundle.getBundle("com.force.i18n.grammaticus");
}
static final ResourceBundle getOverrideProperties() throws MissingResourceException {
return ResourceBundle.getBundle("com.force.i18n.i18n");
}
/**
* @return a jar protocol URL if the given URL is a bundleresource (i.e. osgi)
*/
static URL osgiToJar(URL url) throws IOException {
if ("bundleresource".equalsIgnoreCase(url.getProtocol())) {
// Handle maveny things without referencing osgi directly.
URLConnection connection = url.openConnection();
try {
return(URL) connection.getClass().getMethod("getLocalURL").invoke(connection);
} catch (Exception e) {
throw new IOException(e);
}
}
return url;
}
public static File getFile(URL url) throws URISyntaxException, IOException {
if ("jar".equalsIgnoreCase(url.getProtocol())) {
return (new File(TextUtil.splitSimple("!", url.getFile()).get(0)).getCanonicalFile());
}
return new File(url.toURI()).getCanonicalFile();
}
public static long urlLastModified(URL url) throws URISyntaxException, IOException {
url = osgiToJar(url);
if ("jar".equalsIgnoreCase(url.getProtocol())) {
JarURLConnection jarEntryConn = (JarURLConnection)url.openConnection();
// Check that the jar file actually exists on the file system
File file = new File(jarEntryConn.getJarFileURL().getPath());
if (!file.exists()) throw new IOException("Unable to process JAR url. JAR file is missing: " + file);
try (JarFile jarFile = new JarFile(file)) {
// Automatically reject any JAR URL which does not contain a JAR entry
String jarEntryName = jarEntryConn.getEntryName();
if (jarEntryName == null) throw new IOException("Unsupported JAR url. Missing JAR entry: " + url);
JarEntry jarEntry = jarFile.getJarEntry(jarEntryName);
return jarEntry != null ? jarEntry.getTime() : -1;
}
}
return new File(url.toURI()).lastModified();
}
public static long urlDirLastModified(URL url, boolean includeSubDirs, boolean checkDirectoryTimestampAsWell) throws URISyntaxException, IOException {
if ("jar".equalsIgnoreCase(url.getProtocol())) {
long result = -1;
JarURLConnection jarEntryConn = (JarURLConnection)url.openConnection();
// Check that the jar file actually exists on the file system
File file = new File(jarEntryConn.getJarFileURL().getPath());
if (!file.exists()) throw new IOException("Unable to process JAR url. JAR file is missing: " + file);
// Automatically reject any JAR URL which does not contain a JAR entry
String jarEntryName = jarEntryConn.getEntryName();
try (JarFile jarFile = new JarFile(file)) {
// See if the directory is there
for (Enumeration e =jarFile.entries(); e.hasMoreElements(); ) {
JarEntry entry = e.nextElement();
if (entry.getName().startsWith(jarEntryName)) {
if (!checkDirectoryTimestampAsWell && entry.getName().equals(jarEntryName)) continue;
// TODO: Ignore subdirs
result = Math.max(result, entry.getTime());
}
}
}
return result;
}
assert "file".equalsIgnoreCase(url.getProtocol()) : "Invalid URL protocol: " + url;
return dirLastModified(new File(url.toURI()), includeSubDirs, checkDirectoryTimestampAsWell);
}
/**
* @return the base directory where to put the cache (using the value of cacheDir as a relative
* directory to this). Defaults to current directory. You can also override cacheDir to be
* absolute, and then this is irrelevant.
*/
public static File getCacheBaseDir() {
return CACHE_BASE_DIR;
}
/**
* Set the base directory of where the cache may be stored. This
* way, if you restart the app, it won't need to recalculate the
* cache
* @param cacheDir the cache directory where the label cache will be stored
*/
public static void setCacheBaseDir(File cacheDir) {
CACHE_BASE_DIR = cacheDir;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy