Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft for reading configuration from config files #1722

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.Kit;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.RhinoConfig;
import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
Expand Down Expand Up @@ -132,7 +133,7 @@ public void quit(Context cx, int exitCode) {
*/
public static void main(String args[]) {
try {
if (Boolean.getBoolean("rhino.use_java_policy_security")) {
if (RhinoConfig.getBoolean("rhino.use_java_policy_security")) {
initJavaPolicySecuritySupport();
}
} catch (SecurityException ex) {
Expand Down
167 changes: 167 additions & 0 deletions rhino/src/main/java/org/mozilla/javascript/RhinoConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package org.mozilla.javascript;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Comparator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

/**
* Utility class to read current rhino configuration.
*
* <p>Rhino properties typically begins with "rhino." (properties) or "RHINO_" (env)
*
* <p>The configuration is read from these locations:
*
* <ol>
* <li>rhino.config file from current class' classpath
* <li>rhino.config file from current threas's classpath
* <li>rhino.config file from current directory
* <li>System-properties starting with "rhino."
* <li>env variables starting with "RHINO_" (underscores are replaced by '.' and string is
* </ol>
*
* The config files are in UTF-8 format and all keys in this configuration are case-insensitive and
* dot/underscore-insensitive.
*
* <p>This means, "rhino.use_java_policy_security" is equvalent to "RHINO_USE_JAVA_POLICY_SECURITY"
*
* @author Roland Praml, Foconis Analytics GmbH
*/
public class RhinoConfig {
private static final Map<String, String> PROPERTIES =
AccessController.doPrivileged((PrivilegedAction<Map<String, String>>) () -> init());

private static Map<String, String> init() {
// we have to add a comparator at least for environment: TODO: can this done simpler
Comparator<String> comparator =
(s1, s2) -> {
s1 = s1.toLowerCase(Locale.ROOT).replace('_', '.');
s2 = s2.toLowerCase(Locale.ROOT).replace('_', '.');
return s1.compareTo(s2);
};
Map<String, String> map = new TreeMap<>(comparator);

// load from classpaths
map.putAll(loadFromClasspath(RhinoConfig.class.getClassLoader()));
map.putAll(loadFromClasspath(Thread.currentThread().getContextClassLoader()));
map.putAll(loadFromFile(new File("rhino.config")));
copyMap(System.getProperties(), map);
copyMap(System.getenv(), map);
System.out.println("Current config: " + map);
return map;
}

/** Copies all rhino relevant properties. */
private static void copyMap(Map<?, ?> src, Map<String, String> dst) {
for (Map.Entry<?, ?> entry : src.entrySet()) {
if (entry.getKey() instanceof String && entry.getValue() instanceof String) {
String key = (String) entry.getKey();
if (key.startsWith("rhino.") || key.startsWith("RHINO_")) {
dst.put(key, (String) entry.getValue());
}
}
}
}

@SuppressWarnings("unchecked")
private static Map<String, String> loadFromFile(File config) {
if (config.exists()) {
try (InputStream in = new FileInputStream(config)) {
if (in != null) {
Properties props = new Properties();
props.load(new InputStreamReader(in, StandardCharsets.UTF_8));
System.out.println(
"Loaded rhino.config from "
+ config.getAbsolutePath()); // TODO: remove these prints
return (Map) props;
}
} catch (IOException e) {
System.err.println(
"Error loading rhino.config from "
+ config.getAbsolutePath()
+ ": "
+ e.getMessage());
}
}
return Collections.emptyMap();
}

@SuppressWarnings("unchecked")
private static Map<String, String> loadFromClasspath(ClassLoader cl) {
if (cl != null) {
try (InputStream in = cl.getResourceAsStream("rhino.config")) {
if (in != null) {
Properties props = new Properties();
props.load(new InputStreamReader(in, StandardCharsets.UTF_8));
System.out.println(
"Loaded "
+ props.size()
+ " proerties from rhino.config in classpath"); // TODO: remove
// these prints
return (Map) props;
}
} catch (IOException e) {
System.err.println("Error loading rhino.config from classpath: " + e.getMessage());
}
}
return Collections.emptyMap();
}

/** Replacement for {@link System#getProperty(String)}. */
public static String getProperty(String key) {
return PROPERTIES.get(key);
}

/** Replacement for {@link System#getProperty(String, String)}. */
public static String getProperty(String key, String defaultValue) {
String val = getProperty(key);
return (val == null) ? defaultValue : val;
}

/** Replacement for {@link Boolean#getBoolean(String)}. */
public static boolean getBoolean(String name) {
boolean result = false;
try {
result = Boolean.parseBoolean(getProperty(name));
} catch (IllegalArgumentException | NullPointerException e) {
}
return result;
}

/** Replacement for {@link Integer#getInteger(String, Integer)}. */
public static Integer getInteger(String nm, Integer val) {
String v = null;
try {
v = getProperty(nm);
} catch (IllegalArgumentException | NullPointerException e) {
}
if (v != null) {
try {
return Integer.decode(v);
} catch (NumberFormatException e) {
}
}
return val;
}

/** Replacement for {@link Integer#getInteger(String, int)}. */
public static Integer getInteger(String nm, int val) {
Integer result = getInteger(nm, null);
return (result == null) ? Integer.valueOf(val) : result;
}

/** Replacement for {@link Integer#getInteger(String)}. */
public static Integer getInteger(String nm) {
return getInteger(nm, null);
}
}
26 changes: 10 additions & 16 deletions rhino/src/main/java/org/mozilla/javascript/RhinoException.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.io.FilenameFilter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -221,11 +220,11 @@ static String formatStackTrace(ScriptStackElement[] stack, String message) {
/**
* Get a string representing the script stack of this exception.
*
* @deprecated the filter argument is ignored as we are able to recognize script stack elements
* by our own. Use #getScriptStackTrace() instead.
* @param filter ignored
* @return a script stack dump
* @since 1.6R6
* @deprecated the filter argument is ignored as we are able to recognize script stack elements
* by our own. Use #getScriptStackTrace() instead.
*/
@Deprecated
public String getScriptStackTrace(FilenameFilter filter) {
Expand Down Expand Up @@ -387,20 +386,15 @@ public static StackStyle getStackStyle() {

// Allow us to override default stack style for debugging.
static {
try {
String style = System.getProperty("rhino.stack.style");
if (style != null) {
if ("Rhino".equalsIgnoreCase(style)) {
stackStyle = StackStyle.RHINO;
} else if ("Mozilla".equalsIgnoreCase(style)) {
stackStyle = StackStyle.MOZILLA;
} else if ("V8".equalsIgnoreCase(style)) {
stackStyle = StackStyle.V8;
}
String style = RhinoConfig.getProperty("rhino.stack.style");
if (style != null) {
if ("Rhino".equalsIgnoreCase(style)) {
stackStyle = StackStyle.RHINO;
} else if ("Mozilla".equalsIgnoreCase(style)) {
stackStyle = StackStyle.MOZILLA;
} else if ("V8".equalsIgnoreCase(style)) {
stackStyle = StackStyle.V8;
}
} catch (AccessControlException ace) {
// ignore. We will land here, if SecurityManager is in place and error is lazily
// initialized
}
}
}
1 change: 1 addition & 0 deletions tests/rhino.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rhino.helloFromFile=true
1 change: 1 addition & 0 deletions tests/src/test/resources/rhino.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rhino.helloFromClasspath=true
Loading