diff options
author | Omair Majid <[email protected]> | 2010-12-13 17:28:01 -0500 |
---|---|---|
committer | Omair Majid <[email protected]> | 2010-12-13 17:28:01 -0500 |
commit | 41bd2f399b754a0cba5dd64ce5f32191cfe9ea38 (patch) | |
tree | e91c13e3cfb0922f317bc3ec5a6b14e7730354af /netx/net/sourceforge/jnlp/config | |
parent | bc761e95c6063aaf68e02f7346ad1e10953788da (diff) |
add support for validating configuration
2010-12-13 Omair Majid <[email protected]>
* netx/net/sourceforge/jnlp/config/ValueValidator.java: New file.
* netx/net/sourceforge/jnlp/config/BasicValueValidators.java: New
file. Provides methods to get some common validators.
* netx/net/sourceforge/jnlp/config/ConfiguratonValidator.java: New
file. Provides methods to validate a configuration.
* netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java:
Moved to config subpackage instead and split off into Setting.java,
DeploymentConfiguration.java and Defaults.java.
* netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java:
Renamed version of original DeploymentConfiguration.
(load): Delegate to load.
(load(boolean)): Load configuration and optionally fix any issues
found.
(checkAndFixConfiguration): New method. Validate all settings and
set them to default values if problems found.
* netx/net/sourceforge/jnlp/config/Setting.java: New file. Based on
ConfigValue which was originally a part of DeploymentConfiguration.
* netx/net/sourceforge/jnlp/config/Defaults.java: New file.
Contains the default configuration settings. Originally from
DeploymentConfiguration.java's loadDefaultProperties.
* netx/net/sourceforge/jnlp/resources/Messages.properties: Add new
messages.
* netx/net/sourceforge/jnlp/Launcher.java: Fix imports.
* netx/net/sourceforge/jnlp/SecurityDesc.java: Likewise.
* netx/net/sourceforge/jnlp/cache/CacheUtil.java: Likewise.
* netx/net/sourceforge/jnlp/controlpanel
/AdvancedProxySettingsDialog.java: Likewise
* netx/net/sourceforge/jnlp/controlpanel
/AdvancedProxySettingsPane.java: Likewise.
* netx/net/sourceforge/jnlp/controlpanel/ControlPanel.java: Likewise
* netx/net/sourceforge/jnlp/controlpanel/DebuggingPanel.java:
Likewise.
* netx/net/sourceforge/jnlp/controlpanel/DesktopShortcutPanel.java:
Likewise.
* netx/net/sourceforge/jnlp/controlpanel/MiddleClickListener.java:
Likewise
* netx/net/sourceforge/jnlp/controlpanel/NetworkSettingsPanel.java:
Likewise.
* netx/net/sourceforge/jnlp/controlpanel/SecuritySettingsPanel.java:
Likewise.
* netx/net/sourceforge/jnlp/controlpanel
/TemporaryInternetFilesPanel.java:Likewise.
* netx/net/sourceforge/jnlp/runtime/ApplicationInstance.java:
Likewise.
* netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java:
Likewise.
* netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java: Likewise.
* netx/net/sourceforge/jnlp/security/KeyStores.java: Likewise.
* netx/net/sourceforge/jnlp/security/SecurityWarning.java: Likewise.
* netx/net/sourceforge/jnlp/services/ServiceUtil.java: Likewise.
* netx/net/sourceforge/jnlp/services/SingleInstanceLock.java:
Likewise.
* netx/net/sourceforge/jnlp/services/XBasicService.java: Likewise
* netx/net/sourceforge/jnlp/services/XPersistenceService.java:
Likewise.
* netx/net/sourceforge/jnlp/util/XDesktopEntry.java: Likewise.
* plugin/icedteanp/java/sun/applet/JavaConsole.java: Likewise.
* plugin/icedteanp/java/sun/applet/PluginMain.java: Likewise.
Diffstat (limited to 'netx/net/sourceforge/jnlp/config')
-rw-r--r-- | netx/net/sourceforge/jnlp/config/BasicValueValidators.java | 268 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/config/ConfiguratonValidator.java | 120 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/config/Defaults.java | 394 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java | 611 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/config/Setting.java | 176 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/config/ValueValidator.java | 66 |
6 files changed, 1635 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/config/BasicValueValidators.java b/netx/net/sourceforge/jnlp/config/BasicValueValidators.java new file mode 100644 index 0000000..1cb2af7 --- /dev/null +++ b/netx/net/sourceforge/jnlp/config/BasicValueValidators.java @@ -0,0 +1,268 @@ +/* BasicValueCheckers.java + Copyright (C) 2010 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.config; + +import static net.sourceforge.jnlp.runtime.Translator.R; + +import java.net.URL; +import java.util.Arrays; +import java.util.Locale; + +/** + * Provides {@link ValueValidator} implementations for some common value types + * + * @see #getBooleanValidator() + * @see #getFilePathValidator() + * @see #getRangedIntegerValidator(int, int) + * @see #getStringValidator(String[]) + * @see #getUrlValidator() + */ +public class BasicValueValidators { + + /** + * Checks if a value is a valid boolean + */ + private static class BooleanValidator implements ValueValidator { + + @Override + public void validate(Object value) throws IllegalArgumentException { + Object possibleValue = value; + + if (possibleValue instanceof String) { + String lower = ((String) possibleValue).toLowerCase(Locale.ENGLISH); + if (lower.equals(Boolean.TRUE.toString()) + || (lower.equals(Boolean.FALSE.toString()))) { + possibleValue = Boolean.valueOf(lower); + } + } + + if (!(possibleValue instanceof Boolean)) { + throw new IllegalArgumentException(); + } + } + + @Override + public String getPossibleValues() { + return R("VVPossibleBooleanValues", Boolean.TRUE.toString(), Boolean.FALSE.toString()); + } + }; + + /** + * Checks if a value is a valid file path (not a valid file!). The actual + * file may or may not exist + */ + private static class FilePathValidator implements ValueValidator { + + @Override + public void validate(Object value) throws IllegalArgumentException { + if (value == null) { + return; + } + + Object possibleValue = value; + + if (!(possibleValue instanceof String)) { + throw new IllegalArgumentException(); + } + + String possibleFile = (String) possibleValue; + if (!(possibleFile.startsWith("/"))) { + throw new IllegalArgumentException(); + } + + } + + @Override + public String getPossibleValues() { + return R("VVPossibleFileValues"); + } + + } + + /** + * Checks that the value is an Integer or Long (or a String representation + * of one) that is within a desired range). + */ + private static class RangedIntegerValidator implements ValueValidator { + private int low = 0; + private int high = 0; + + public RangedIntegerValidator(int low, int high) { + this.low = low; + this.high = high; + } + + @Override + public void validate(Object value) throws IllegalArgumentException { + Object possibleValue = value; + + long actualValue = 0; + try { + if (possibleValue instanceof String) { + actualValue = Long.valueOf((String) possibleValue); + } else if (possibleValue instanceof Integer) { + actualValue = (Integer) possibleValue; + } else if (possibleValue instanceof Long) { + actualValue = (Long) possibleValue; + } else { + throw new IllegalArgumentException("Must be an integer"); + } + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Must be an integer"); + + } + + if (actualValue < low || actualValue > high) { + throw new IllegalArgumentException("Not in range from " + low + " to " + high); + } + } + + @Override + public String getPossibleValues() { + return R("VVPossibleRangedIntegerValues", low, high); + } + + }; + + /** + * Checks that the value is one of the acceptable String values + */ + private static class StringValueValidator implements ValueValidator { + String[] options = null; + + public StringValueValidator(String[] acceptableOptions) { + options = acceptableOptions; + } + + @Override + public void validate(Object value) throws IllegalArgumentException { + Object possibleValue = value; + if (!(possibleValue instanceof String)) { + throw new IllegalArgumentException("Must be a string"); + } + + String stringVal = (String) possibleValue; + boolean found = false; + for (String knownVal : options) { + if (knownVal.equals(stringVal)) { + found = true; + break; + } + } + + if (!found) { + throw new IllegalArgumentException(); + } + } + + @Override + public String getPossibleValues() { + return Arrays.toString(options); + } + + } + + /** + * Checks that the value is a URL + */ + private static class UrlValidator implements ValueValidator { + + @Override + public void validate(Object value) throws IllegalArgumentException { + if (value == null) { + return; + } + try { + new URL((String) value); + } catch (Exception e) { + throw new IllegalArgumentException(); + } + } + + @Override + public String getPossibleValues() { + return R("VVPossibleUrlValues"); + } + + } + + /** + * @return a {@link ValueValidator} that can be used to check if an object is + * a valid Boolean + */ + public static ValueValidator getBooleanValidator() { + return new BooleanValidator(); + } + + /** + * @return a {@link ValueValidator} that can be used to check if an object is + * a String containing a valid file path or not + */ + public static ValueValidator getFilePathValidator() { + return new FilePathValidator(); + } + + /** + * Returns a {@link ValueValidator} that checks if an object represents a + * valid integer (it is a Integer or Long or a String representation of + * one), within the given range. The values are inclusive. + * @param low the lowest valid value + * @param high the highest valid value + */ + public static ValueValidator getRangedIntegerValidator(int low, int high) { + return new RangedIntegerValidator(low, high); + } + + /** + * Returns a {@link ValueValidator} that checks if an object is a string from + * one of the provided Strings. + * @param validValues an array of Strings which are considered valid + */ + public static ValueValidator getStringValidator(String[] validValues) { + return new StringValueValidator(validValues); + } + + /** + * @return a {@link ValueValidator} that checks if an object represents a + * valid url + */ + public static ValueValidator getUrlValidator() { + return new UrlValidator(); + } + +} diff --git a/netx/net/sourceforge/jnlp/config/ConfiguratonValidator.java b/netx/net/sourceforge/jnlp/config/ConfiguratonValidator.java new file mode 100644 index 0000000..2ec4c5b --- /dev/null +++ b/netx/net/sourceforge/jnlp/config/ConfiguratonValidator.java @@ -0,0 +1,120 @@ +/* Validator.java + Copyright (C) 2010 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.config; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Validates a DeploymentConfiguration by identifying settings with + * unrecognized names or incorrect values. + */ +public class ConfiguratonValidator { + + private List<Setting<String>> incorrectEntries; + private List<Setting<String>> unrecognizedEntries; + private Map<String, Setting<String>> toValidate = null; + + private boolean validated = false; + + /** + * @param toValidate the settings to validate + */ + public ConfiguratonValidator(Map<String, Setting<String>> toValidate) { + this.toValidate = toValidate; + } + + /** + * Validates the settings used in the constructor. Use + * {@link #getIncorrectSetting()} and {@link #getUnrecognizedSetting()} to + * get the list of incorrect or unrecognized settings. + */ + public void validate() { + incorrectEntries = new ArrayList<Setting<String>>(); + unrecognizedEntries = new ArrayList<Setting<String>>(); + + Map<String, Setting<String>> knownGood = Defaults.getDefaults(); + + for (String key : toValidate.keySet()) { + // check for known incorrect settings + if (knownGood.containsKey(key)) { + Setting<String> good = knownGood.get(key); + Setting<String> unknown = toValidate.get(key); + ValueValidator checker = good.getValidator(); + if (checker != null) { + try { + checker.validate(unknown.getValue()); + } catch (IllegalArgumentException e) { + Setting<String> strange = new Setting<String>(unknown); + strange.setValue(unknown.getValue()); + incorrectEntries.add(strange); + } + } + } else { + // check for unknown settings + Setting<String> strange = new Setting<String>(toValidate.get(key)); + unrecognizedEntries.add(strange); + } + } + + validated = true; + } + + /** + * @return a list of settings which have incorrect values + */ + public List<Setting<String>> getIncorrectSetting() { + if (!validated) { + throw new IllegalStateException(); + } + + return new ArrayList<Setting<String>>(incorrectEntries); + } + + /** + * @return a list of settings which are not recognized + */ + public List<Setting<String>> getUnrecognizedSetting() { + if (!validated) { + throw new IllegalStateException(); + } + return new ArrayList<Setting<String>>(unrecognizedEntries); + } + +} diff --git a/netx/net/sourceforge/jnlp/config/Defaults.java b/netx/net/sourceforge/jnlp/config/Defaults.java new file mode 100644 index 0000000..78e203d --- /dev/null +++ b/netx/net/sourceforge/jnlp/config/Defaults.java @@ -0,0 +1,394 @@ +/* Defaults.java + Copyright (C) 2010 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.config; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.jnlp.ShortcutDesc; +import net.sourceforge.jnlp.runtime.JNLPProxySelector; + +/** + * This class stores the default configuration + */ +public class Defaults { + + /** + * Get the default settings for deployment + */ + public static Map<String, Setting<String>> getDefaults() { + File userFile = new File(System.getProperty("user.home") + File.separator + DeploymentConfiguration.DEPLOYMENT_DIR + + File.separator + DeploymentConfiguration.DEPLOYMENT_PROPERTIES); + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkRead(userFile.toString()); + } + + final String SYSTEM_HOME = System.getProperty("java.home"); + final String SYSTEM_SECURITY = SYSTEM_HOME + File.separator + "lib" + File.separator + "security"; + + final String USER_HOME = System.getProperty("user.home") + File.separator + DeploymentConfiguration.DEPLOYMENT_DIR; + final String USER_SECURITY = USER_HOME + File.separator + "security"; + + final String LOCKS_DIR = System.getProperty("java.io.tmpdir") + File.separator + + System.getProperty("user.name") + File.separator + "netx" + File.separator + + "locks"; + + /* + * This is more or less a straight copy from the deployment + * configuration page, with occasional replacements of "" or no-defaults + * with null + * + * The format of this is: + * name + * checker (can be null or a ValueChecker) + * value (can be null or a String) + */ + + Object[][] defaults = new Object[][] { + /* infrastructure */ + { + DeploymentConfiguration.KEY_USER_CACHE_DIR, + BasicValueValidators.getFilePathValidator(), + USER_HOME + File.separator + "cache" + }, + { + DeploymentConfiguration.KEY_USER_PERSISTENCE_CACHE_DIR, + BasicValueValidators.getFilePathValidator(), + USER_HOME + File.separator + "pcache" + }, + { + DeploymentConfiguration.KEY_SYSTEM_CACHE_DIR, + BasicValueValidators.getFilePathValidator(), + null + }, + { + DeploymentConfiguration.KEY_USER_LOG_DIR, + BasicValueValidators.getFilePathValidator(), + USER_HOME + File.separator + "log" + }, + { + DeploymentConfiguration.KEY_USER_TMP_DIR, + BasicValueValidators.getFilePathValidator(), + USER_HOME + File.separator + "tmp" + }, + { + DeploymentConfiguration.KEY_USER_LOCKS_DIR, + BasicValueValidators.getFilePathValidator(), + LOCKS_DIR + }, + { + DeploymentConfiguration.KEY_USER_NETX_RUNNING_FILE, + BasicValueValidators.getFilePathValidator(), + LOCKS_DIR + File.separator + "netx_running" + }, + /* certificates and policy files */ + { + DeploymentConfiguration.KEY_USER_SECURITY_POLICY, + BasicValueValidators.getUrlValidator(), + "file://" + USER_SECURITY + File.separator + "java.policy" + }, + { + DeploymentConfiguration.KEY_USER_TRUSTED_CA_CERTS, + BasicValueValidators.getFilePathValidator(), + USER_SECURITY + File.separator + "trusted.cacerts" + }, + { + DeploymentConfiguration.KEY_USER_TRUSTED_JSSE_CA_CERTS, + BasicValueValidators.getFilePathValidator(), + USER_SECURITY + File.separator + "trusted.jssecacerts" + }, + { + DeploymentConfiguration.KEY_USER_TRUSTED_CERTS, + BasicValueValidators.getFilePathValidator(), + USER_SECURITY + File.separator + "trusted.certs" + }, + { + DeploymentConfiguration.KEY_USER_TRUSTED_JSSE_CERTS, + BasicValueValidators.getFilePathValidator(), + USER_SECURITY + File.separator + "trusted.jssecerts" + }, + { + DeploymentConfiguration.KEY_USER_TRUSTED_CLIENT_CERTS, + BasicValueValidators.getFilePathValidator(), + USER_SECURITY + File.separator + "trusted.clientcerts" + }, + { + DeploymentConfiguration.KEY_SYSTEM_SECURITY_POLICY, + BasicValueValidators.getUrlValidator(), + null + }, + { + DeploymentConfiguration.KEY_SYSTEM_TRUSTED_CA_CERTS, + BasicValueValidators.getFilePathValidator(), + SYSTEM_SECURITY + File.separator + "cacerts" + }, + { + DeploymentConfiguration.KEY_SYSTEM_TRUSTED_JSSE_CA_CERTS, + BasicValueValidators.getFilePathValidator(), + SYSTEM_SECURITY + File.separator + "jssecacerts" + }, + { + DeploymentConfiguration.KEY_SYSTEM_TRUSTED_CERTS, + BasicValueValidators.getFilePathValidator(), + SYSTEM_SECURITY + File.separator + "trusted.certs" + }, + { + DeploymentConfiguration.KEY_SYSTEM_TRUSTED_JSSE_CERTS, + BasicValueValidators.getFilePathValidator(), + SYSTEM_SECURITY + File.separator + "trusted.jssecerts" + }, + { + DeploymentConfiguration.KEY_SYSTEM_TRUSTED_CLIENT_CERTS, + BasicValueValidators.getFilePathValidator(), + SYSTEM_SECURITY + File.separator + "trusted.clientcerts" + }, + /* security access and control */ + { + DeploymentConfiguration.KEY_SECURITY_PROMPT_USER, + BasicValueValidators.getBooleanValidator(), + String.valueOf(true) + }, + { + "deployment.security.askgrantdialog.notinca", + BasicValueValidators.getBooleanValidator(), + String.valueOf(true) + }, + { + "deployment.security.notinca.warning", + BasicValueValidators.getBooleanValidator(), + String.valueOf(true) + }, + { + "deployment.security.expired.warning", + BasicValueValidators.getBooleanValidator(), + String.valueOf(true) + }, + { + "deployment.security.jsse.hostmismatch.warning", + BasicValueValidators.getBooleanValidator(), + String.valueOf(true) + }, + { + "deployment.security.trusted.policy", + BasicValueValidators.getFilePathValidator(), + null + }, + { + DeploymentConfiguration.KEY_SECURITY_ALLOW_HIDE_WINDOW_WARNING, + BasicValueValidators.getBooleanValidator(), + String.valueOf(true) + }, + { + DeploymentConfiguration.KEY_SECURITY_PROMPT_USER_FOR_JNLP, + BasicValueValidators.getBooleanValidator(), + String.valueOf(true) + }, + { + DeploymentConfiguration.KEY_SECURITY_INSTALL_AUTHENTICATOR, + BasicValueValidators.getBooleanValidator(), + String.valueOf(true) + }, + /* networking */ + { + DeploymentConfiguration.KEY_PROXY_TYPE, + BasicValueValidators.getRangedIntegerValidator(JNLPProxySelector.PROXY_TYPE_UNKNOWN, JNLPProxySelector.PROXY_TYPE_BROWSER), + String.valueOf(JNLPProxySelector.PROXY_TYPE_BROWSER) + }, + { + DeploymentConfiguration.KEY_PROXY_SAME, + BasicValueValidators.getBooleanValidator(), + String.valueOf(false) + }, + { + DeploymentConfiguration.KEY_PROXY_AUTO_CONFIG_URL, + BasicValueValidators.getUrlValidator(), + null + }, + { + DeploymentConfiguration.KEY_PROXY_BYPASS_LIST, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_BYPASS_LOCAL, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_HTTP_HOST, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_HTTP_PORT, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_HTTPS_HOST, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_HTTPS_PORT, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_FTP_HOST, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_FTP_PORT, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_SOCKS4_HOST, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_SOCKS4_PORT, + null, + null + }, + { + DeploymentConfiguration.KEY_PROXY_OVERRIDE_HOSTS, + null, + null + }, + /* cache and optional package repository */ + { + "deployment.cache.max.size", + BasicValueValidators.getRangedIntegerValidator(-1, Integer.MAX_VALUE), + String.valueOf("-1") + }, + { + "deployment.cache.jarcompression", + BasicValueValidators.getRangedIntegerValidator(0, 10), + String.valueOf(0) + }, + { + "deployment.javapi.cache.enabled", + BasicValueValidators.getBooleanValidator(), + String.valueOf(false) + }, + /* java console */ + { + DeploymentConfiguration.KEY_CONSOLE_STARTUP_MODE, + BasicValueValidators.getStringValidator(new String[] { + DeploymentConfiguration.CONSOLE_DISABLE, + DeploymentConfiguration.CONSOLE_HIDE, + DeploymentConfiguration.CONSOLE_SHOW + }), + DeploymentConfiguration.CONSOLE_HIDE + }, + /* tracing and logging */ + { + DeploymentConfiguration.KEY_ENABLE_TRACING, + BasicValueValidators.getBooleanValidator(), + String.valueOf(false) + }, + { + DeploymentConfiguration.KEY_ENABLE_LOGGING, + BasicValueValidators.getBooleanValidator(), + String.valueOf(false) + }, + /* JNLP association */ + { + DeploymentConfiguration.KEY_JNLP_ASSOCIATIONS, + BasicValueValidators.getRangedIntegerValidator(DeploymentConfiguration.JNLP_ASSOCIATION_NEVER, + DeploymentConfiguration.JNLP_ASSOCIATION_REPLACE_ASK), + String.valueOf(DeploymentConfiguration.JNLP_ASSOCIATION_ASK_USER) + }, + /* desktop integration */ + { + DeploymentConfiguration.KEY_CREATE_DESKTOP_SHORTCUT, + BasicValueValidators.getStringValidator(new String[] { + ShortcutDesc.CREATE_ALWAYS, + ShortcutDesc.CREATE_ALWAYS_IF_HINTED, + ShortcutDesc.CREATE_ASK_USER, + ShortcutDesc.CREATE_ASK_USER_IF_HINTED, + ShortcutDesc.CREATE_NEVER + }), + ShortcutDesc.CREATE_ASK_USER_IF_HINTED + }, + /* jre selection */ + { + DeploymentConfiguration.KEY_JRE_INTSTALL_URL, + BasicValueValidators.getUrlValidator(), + null + }, + /* jre management */ + { + DeploymentConfiguration.KEY_AUTO_DOWNLOAD_JRE, + BasicValueValidators.getBooleanValidator(), + String.valueOf(false) + }, + /* browser selection */ + { + DeploymentConfiguration.KEY_BROWSER_PATH, + BasicValueValidators.getFilePathValidator(), + null + }, + /* check for update timeout */ + { + DeploymentConfiguration.KEY_UPDATE_TIMEOUT, + BasicValueValidators.getRangedIntegerValidator(0, 10000), + String.valueOf(500) + } + }; + + HashMap<String, Setting<String>> result = new HashMap<String, Setting<String>>(); + for (int i = 0; i < defaults.length; i++) { + String name = (String) defaults[i][0]; + ValueValidator checker = (ValueValidator) defaults[i][1]; + String actualValue = (String) defaults[i][2]; + boolean locked = false; + Setting<String> value = new Setting<String>(name, name, locked, checker, actualValue, actualValue, "<internal>"); + result.put(name, value); + } + + return result; + } +} diff --git a/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java new file mode 100644 index 0000000..dd329aa --- /dev/null +++ b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java @@ -0,0 +1,611 @@ +// Copyright (C) 2010 Red Hat, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +package net.sourceforge.jnlp.config; + +import static net.sourceforge.jnlp.runtime.Translator.R; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.Reader; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.channels.FileLock; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.naming.ConfigurationException; + +import net.sourceforge.jnlp.runtime.JNLPRuntime; + +/** + * Manages the various properties and configuration related to deployment. + * + * See: + * http://download.oracle.com/javase/1.5.0/docs/guide/deployment/deployment-guide/properties.html + */ +public final class DeploymentConfiguration { + + public static final String DEPLOYMENT_DIR = ".icedtea"; + public static final String DEPLOYMENT_CONFIG = "deployment.config"; + public static final String DEPLOYMENT_PROPERTIES = "deployment.properties"; + + public static final String DEPLOYMENT_COMMENT = "Netx deployment configuration"; + + public static final int JNLP_ASSOCIATION_NEVER = 0; + public static final int JNLP_ASSOCIATION_NEW_ONLY = 1; + public static final int JNLP_ASSOCIATION_ASK_USER = 2; + public static final int JNLP_ASSOCIATION_REPLACE_ASK = 3; + + /* + * FIXME these should be moved into JavaConsole, but there is a strange + * dependency in the build system. First all of netx is built. Then the + * plugin is built. So we cannot refer to plugin code in here :( + */ + public static final String CONSOLE_HIDE = "HIDE"; + public static final String CONSOLE_SHOW = "SHOW"; + public static final String CONSOLE_DISABLE = "DISABLE"; + + public static final String KEY_USER_CACHE_DIR = "deployment.user.cachedir"; + public static final String KEY_USER_PERSISTENCE_CACHE_DIR = "deployment.user.pcachedir"; + public static final String KEY_SYSTEM_CACHE_DIR = "deployment.system.cachedir"; + public static final String KEY_USER_LOG_DIR = "deployment.user.logdir"; + public static final String KEY_USER_TMP_DIR = "deployment.user.tmp"; + /** the directory containing locks for single instance applications */ + public static final String KEY_USER_LOCKS_DIR = "deployment.user.locksdir"; + /** + * The netx_running file is used to indicate if any instances of netx are + * running (this file may exist even if no instances are running). All netx + * instances acquire a shared lock on this file. If this file can be locked + * (using a {@link FileLock}) in exclusive mode, then other netx instances + * are not running + */ + public static final String KEY_USER_NETX_RUNNING_FILE = "deployment.user.runningfile"; + + public static final String KEY_USER_SECURITY_POLICY = "deployment.user.security.policy"; + public static final String KEY_USER_TRUSTED_CA_CERTS = "deployment.user.security.trusted.cacerts"; + public static final String KEY_USER_TRUSTED_JSSE_CA_CERTS = "deployment.user.security.trusted.jssecacerts"; + public static final String KEY_USER_TRUSTED_CERTS = "deployment.user.security.trusted.certs"; + public static final String KEY_USER_TRUSTED_JSSE_CERTS = "deployment.user.security.trusted.jssecerts"; + public static final String KEY_USER_TRUSTED_CLIENT_CERTS = "deployment.user.security.trusted.clientauthcerts"; + + public static final String KEY_SYSTEM_SECURITY_POLICY = "deployment.system.security.policy"; + public static final String KEY_SYSTEM_TRUSTED_CA_CERTS = "deployment.system.security.cacerts"; + public static final String KEY_SYSTEM_TRUSTED_JSSE_CA_CERTS = "deployment.system.security.jssecacerts"; + public static final String KEY_SYSTEM_TRUSTED_CERTS = "deployment.system.security.trusted.certs"; + public static final String KEY_SYSTEM_TRUSTED_JSSE_CERTS = "deployment.system.security.trusted.jssecerts"; + public static final String KEY_SYSTEM_TRUSTED_CLIENT_CERTS = "deployment.system.security.trusted.clientautcerts"; + + /* + * Security and access control + */ + + /** Boolean. Only show security prompts to user if true */ + public static final String KEY_SECURITY_PROMPT_USER = "deployment.security.askgrantdialog.show"; + + /** Boolean. Only give AWTPermission("showWindowWithoutWarningBanner") if true */ + public static final String KEY_SECURITY_ALLOW_HIDE_WINDOW_WARNING = "deployment.security.sandbox.awtwarningwindow"; + + /** Boolean. Only prompt user for granting any JNLP permissions if true */ + public static final String KEY_SECURITY_PROMPT_USER_FOR_JNLP = "deployment.security.sandbox.jnlp.enhanced"; + + /** Boolean. Only install the custom authenticator if true */ + public static final String KEY_SECURITY_INSTALL_AUTHENTICATOR = "deployment.security.authenticator"; + + /* + * Networking + */ + public static final String KEY_PROXY_TYPE = "deployment.proxy.type"; + public static final String KEY_PROXY_SAME = "deployment.proxy.same"; + public static final String KEY_PROXY_AUTO_CONFIG_URL = "deployment.proxy.auto.config.url"; + public static final String KEY_PROXY_BYPASS_LIST = "deployment.proxy.bypass.list"; + public static final String KEY_PROXY_BYPASS_LOCAL = "deployment.proxy.bypass.local"; + public static final String KEY_PROXY_HTTP_HOST = "deployment.proxy.http.host"; + public static final String KEY_PROXY_HTTP_PORT = "deployment.proxy.http.port"; + public static final String KEY_PROXY_HTTPS_HOST = "deployment.proxy.https.host"; + public static final String KEY_PROXY_HTTPS_PORT = "deployment.proxy.https.port"; + public static final String KEY_PROXY_FTP_HOST = "deployment.proxy.ftp.host"; + public static final String KEY_PROXY_FTP_PORT = "deployment.proxy.ftp.port"; + public static final String KEY_PROXY_SOCKS4_HOST = "deployment.proxy.socks.host"; + public static final String KEY_PROXY_SOCKS4_PORT = "deployment.proxy.socks.port"; + public static final String KEY_PROXY_OVERRIDE_HOSTS = "deployment.proxy.override.hosts"; + + /* + * Tracing and Logging + */ + public static final String KEY_ENABLE_TRACING = "deployment.trace"; + public static final String KEY_ENABLE_LOGGING = "deployment.log"; + + /* + * Console + */ + public static final String KEY_CONSOLE_STARTUP_MODE = "deployment.console.startup.mode"; + + /* + * Desktop Integration + */ + + public static final String KEY_JNLP_ASSOCIATIONS = "deployment.javaws.associations"; + public static final String KEY_CREATE_DESKTOP_SHORTCUT = "deployment.javaws.shortcut"; + + public static final String KEY_JRE_INTSTALL_URL = "deployment.javaws.installURL"; + public static final String KEY_AUTO_DOWNLOAD_JRE = "deployment.javaws.autodownload"; + + public static final String KEY_BROWSER_PATH = "deployment.browser.path"; + public static final String KEY_UPDATE_TIMEOUT = "deployment.javaws.update.timeout"; + + public enum ConfigType { + System, User + } + + /** is it mandatory to load the system properties? */ + private boolean systemPropertiesMandatory = false; + + /** The system's deployment.config file */ + private File systemPropertiesFile = null; + /** The user's deployment.config file */ + private File userPropertiesFile = null; + + /** the current deployment properties */ + private Map<String, Setting<String>> currentConfiguration; + + /** the deployment properties that cannot be changed */ + private Map<String, Setting<String>> unchangeableConfiguration; + + public DeploymentConfiguration() { + currentConfiguration = new HashMap<String, Setting<String>>(); + unchangeableConfiguration = new HashMap<String, Setting<String>>(); + } + + /** + * Initialize this deployment configuration by reading configuration files. + * Generally, it will try to continue and ignore errors it finds (such as file not found). + * + * @throws DeploymentException if it encounters a fatal error. + */ + public void load() throws ConfigurationException { + load(true); + } + + /** + * Initialize this deployment configuration by reading configuration files. + * Generally, it will try to continue and ignore errors it finds (such as file not found). + * + * @param fixIssues If true, fix issues that are discovered when reading configuration by + * resorting to the default values + * @throws DeploymentException if it encounters a fatal error. + */ + public void load(boolean fixIssues) throws ConfigurationException { + // make sure no state leaks if security check fails later on + File userFile = new File(System.getProperty("user.home") + File.separator + DEPLOYMENT_DIR + + File.separator + DEPLOYMENT_PROPERTIES); + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkRead(userFile.toString()); + } + + Map<String, Setting<String>> initialProperties = Defaults.getDefaults(); + + Map<String, Setting<String>> systemProperties = null; + + /* + * First, try to read the system's deployment.config file to find if + * there is a system-level deployment.poperties file + */ + + File systemConfigFile = findSystemConfigFile(); + if (systemConfigFile != null) { + if (loadSystemConfiguration(systemConfigFile)) { + if (JNLPRuntime.isDebug()) { + System.out.println("System level " + DEPLOYMENT_CONFIG + " is mandatory: " + systemPropertiesMandatory); + } + /* Second, read the System level deployment.properties file */ + systemProperties = loadProperties(ConfigType.System, systemPropertiesFile, + systemPropertiesMandatory); + } + if (systemProperties != null) { + mergeMaps(initialProperties, systemProperties); + } + } + + /* need a copy of the original when we have to save */ + unchangeableConfiguration = new HashMap<String, Setting<String>>(); + Set<String> keys = initialProperties.keySet(); + for (String key : keys) { + unchangeableConfiguration.put(key, new Setting<String>(initialProperties.get(key))); + } + + /* + * Third, read the user's deployment.properties file + */ + userPropertiesFile = userFile; + Map<String, Setting<String>> userProperties = loadProperties(ConfigType.User, userPropertiesFile, false); + if (userProperties != null) { + mergeMaps(initialProperties, userProperties); + } + + if (fixIssues) { + checkAndFixConfiguration(initialProperties); + } + + currentConfiguration = initialProperties; + } + + /** + * Get the value for the given key + * + * @param key the property key + * @return the value for the key, or null if it can not be found + */ + public String getProperty(String key) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + if (userPropertiesFile != null) { + sm.checkRead(userPropertiesFile.toString()); + } + } + + return currentConfiguration.get(key).getValue(); + } + + /** + * @return a Set containing all the property names + */ + public Set<String> getAllPropertyNames() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + if (userPropertiesFile != null) { + sm.checkRead(userPropertiesFile.toString()); + } + } + + return currentConfiguration.keySet(); + } + + /** + * @return a map containing property names and the corresponding settings + */ + public Map<String, Setting<String>> getRaw() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + if (userPropertiesFile != null) { + sm.checkRead(userPropertiesFile.toString()); + } + } + + return currentConfiguration; + } + + /** + * Sets the value of corresponding to the key. If the value has been marked + * as locked, it is not changed + * + * @param key the key + * @param value the value to be associated with the key + */ + public void setProperty(String key, String value) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + if (userPropertiesFile != null) { + sm.checkWrite(userPropertiesFile.toString()); + } + } + + Setting<String> currentValue = currentConfiguration.get(key); + if (currentValue != null) { + if (!currentValue.isLocked()) { + currentValue.setValue(value); + } + } else { + currentValue = new Setting<String>(key, key, false, null, null, value, "<unknown>"); + currentConfiguration.put(key, currentValue); + } + } + + /** + * Check that the configuration is valid. If there are invalid values,set + * those values to the default values. This is done by using check() + * method of the ValueCheker for each setting on the actual value. Fixes + * are made in-place. + * + * @param initial a map representing the initial configuration + */ + public void checkAndFixConfiguration(Map<String, Setting<String>> initial) { + + Map<String, Setting<String>> defaults = Defaults.getDefaults(); + + for (String key : initial.keySet()) { + Setting<String> s = initial.get(key); + if (!(s.getName().equals(key))) { + System.out.println(R("DCInternal", "key " + key + " does not match setting name " + s.getName())); + } else if (!defaults.containsKey(key)) { + System.out.println(R("DCUnknownSettingWithVal", key)); + } else { + ValueValidator checker = defaults.get(key).getValidator(); + if (checker == null) { + continue; + } + + try { + checker.validate(s.getValue()); + } catch (IllegalArgumentException e) { + System.out.println(R("DCErrorInSetting", key, s.getValue(), s.getDefaultValue(), checker.getPossibleValues())); + s.setValue(s.getDefaultValue()); + } + } + } + } + + /** + * @return the location of system-level deployment.config file, or null if none can be found + */ + private File findSystemConfigFile() { + File etcFile = new File(File.separator + "etc" + File.separator + ".java" + File.separator + + "deployment" + File.separator + DEPLOYMENT_CONFIG); + if (etcFile.isFile()) { + return etcFile; + } + + File jreFile = new File(System.getProperty("java.home") + File.separator + "lib" + + File.separator + DEPLOYMENT_CONFIG); + if (jreFile.isFile()) { + return jreFile; + } + + return null; + } + + /** + * Reads the system configuration file and sets the relevant + * system-properties related variables + */ + private boolean loadSystemConfiguration(File configFile) { + + if (JNLPRuntime.isDebug()) { + System.out.println("Loading system configuation from: " + configFile); + } + + Map<String, Setting<String>> systemConfiguration = new HashMap<String, Setting<String>>(); + try { + systemConfiguration = parsePropertiesFile(configFile); + } catch (IOException e) { + if (JNLPRuntime.isDebug()) { + System.out.println("No System level " + DEPLOYMENT_PROPERTIES + " found."); + } + return false; + } + + /* + * at this point, we have read the system deployment.config file + * completely + */ + + try { + String urlString = systemConfiguration.get("deployment.system.config").getValue(); + if (urlString == null) { + if (JNLPRuntime.isDebug()) { + System.out.println("No System level " + DEPLOYMENT_PROPERTIES + " found."); + } + return false; + } + URL url = new URL(urlString); + if (url.getProtocol().equals("file")) { + systemPropertiesFile = new File(url.getFile()); + if (JNLPRuntime.isDebug()) { + System.out.println("Using System level" + DEPLOYMENT_PROPERTIES + ": " + + systemPropertiesFile); + } + Setting<String> mandatory = systemConfiguration.get("deployment.system.config.mandatory"); + systemPropertiesMandatory = Boolean.valueOf(mandatory == null ? null : (String) mandatory.getValue()); + return true; + } else { + if (JNLPRuntime.isDebug()) { + System.out.println("Remote + " + DEPLOYMENT_PROPERTIES + " not supported"); + } + return false; + } + } catch (MalformedURLException e) { + if (JNLPRuntime.isDebug()) { + System.out.println("Invalid url for " + DEPLOYMENT_PROPERTIES); + } + return false; + } + } + + /** + * Loads the properties file, if one exists + * + * @param type the ConfigType to load + * @param file the File to load Properties from + * @param mandatory indicates if reading this file is mandatory + * + * @throws ConfigurationException if the file is mandatory but cannot be read + */ + private Map<String, Setting<String>> loadProperties(ConfigType type, File file, boolean mandatory) + throws ConfigurationException { + if (file == null || !file.isFile()) { + if (JNLPRuntime.isDebug()) { + System.out.println("No " + type.toString() + " level " + DEPLOYMENT_PROPERTIES + " found."); + } + if (!mandatory) { + return null; + } else { + throw new ConfigurationException(); + } + } + + if (JNLPRuntime.isDebug()) { + System.out.println("Loading " + type.toString() + " level properties from: " + file); + } + try { + return parsePropertiesFile(file); + } catch (IOException e) { + return null; + } + } + + /** + * Saves all properties that are not part of default or system properties + * + * @throws IOException if unable to save the file + * @throws IllegalStateException if save() is called before load() + */ + public void save() throws IOException { + if (userPropertiesFile == null) { + throw new IllegalStateException("must load() before save()"); + } + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkWrite(userPropertiesFile.toString()); + } + + if (JNLPRuntime.isDebug()) { + System.out.println("Saving properties into " + userPropertiesFile.toString()); + } + Properties toSave = new Properties(); + + for (String key : currentConfiguration.keySet()) { + String oldValue = unchangeableConfiguration.get(key) == null ? null + : (String) unchangeableConfiguration.get(key).getValue(); + String newValue = currentConfiguration.get(key) == null ? null : (String) currentConfiguration + .get(key).getValue(); + if (oldValue == null && newValue == null) { + continue; + } else if (oldValue == null && newValue != null) { + toSave.setProperty(key, newValue); + } else if (oldValue != null && newValue == null) { + toSave.setProperty(key, newValue); + } else { // oldValue != null && newValue != null + if (!oldValue.equals(newValue)) { + toSave.setProperty(key, newValue); + } + } + } + + File backupPropertiesFile = new File(userPropertiesFile.toString() + ".old"); + if (userPropertiesFile.isFile()) { + if (!userPropertiesFile.renameTo(backupPropertiesFile)) { + throw new IOException("Error saving backup copy of " + userPropertiesFile); + } + } + + userPropertiesFile.getParentFile().mkdirs(); + OutputStream out = new BufferedOutputStream(new FileOutputStream(userPropertiesFile)); + try { + toSave.store(out, DEPLOYMENT_COMMENT); + } finally { + out.close(); + } + } + + /** + * Reads a properties file and returns a map representing the properties + * + * @param propertiesFile the file to read Properties from + * @param destination the map to which all the properties should be added + * @throws IOException if an IO problem occurs + */ + private Map<String, Setting<String>> parsePropertiesFile(File propertiesFile) throws IOException { + Map<String, Setting<String>> result = new HashMap<String, Setting<String>>(); + + Properties properties = new Properties(); + + Reader reader = new BufferedReader(new FileReader(propertiesFile)); + try { + properties.load(reader); + } finally { + reader.close(); + } + + Set<String> keys = properties.stringPropertyNames(); + for (String key : keys) { + if (key.endsWith(".locked")) { + String realKey = key.substring(0, key.length() - ".locked".length()); + Setting<String> configValue = result.get(realKey); + if (configValue == null) { + configValue = new Setting<String>(realKey, realKey, true, null, null, null, propertiesFile.toString()); + result.put(realKey, configValue); + } else { + configValue.setLocked(true); + } + } else { + /* when parsing a properties we set value without checking if it is locked or not */ + String newValue = properties.getProperty(key); + Setting<String> configValue = result.get(key); + if (configValue == null) { + configValue = new Setting<String>(key, key, false, null, null, newValue, propertiesFile.toString()); + result.put(key, configValue); + } else { + configValue.setValue(newValue); + configValue.setSource(propertiesFile.toString()); + } + } + } + return result; + } + + /** + * Merges two maps while respecting whether the values have been locked or + * not. All values from srcMap are put into finalMap, replacing values in + * finalMap if necessary, unless the value is present and marked as locked + * in finalMap + * + * @param finalMap the destination for putting values + * @param srcMap the source for reading key value pairs + */ + private void mergeMaps(Map<String, Setting<String>> finalMap, Map<String, Setting<String>> srcMap) { + for (String key : srcMap.keySet()) { + Setting<String> destValue = finalMap.get(key); + Setting<String> srcValue = srcMap.get(key); + if (destValue == null) { + finalMap.put(key, srcValue); + } else { + if (!destValue.isLocked()) { + destValue.setSource(srcValue.getSource()); + destValue.setValue(srcValue.getValue()); + } + } + } + } + + /** + * Dumps the configuration to the PrintStream + * + * @param config a map of key,value pairs representing the configuration to + * dump + * @param out the PrintStream to write data to + */ + @SuppressWarnings("unused") + private static void dumpConfiguration(Map<String, Setting<String>> config, PrintStream out) { + System.out.println("KEY: VALUE [Locked]"); + + for (String key : config.keySet()) { + Setting<String> value = config.get(key); + out.println("'" + key + "': '" + value.getValue() + "'" + + (value.isLocked() ? " [LOCKED]" : "")); + } + } +} diff --git a/netx/net/sourceforge/jnlp/config/Setting.java b/netx/net/sourceforge/jnlp/config/Setting.java new file mode 100644 index 0000000..34faacc --- /dev/null +++ b/netx/net/sourceforge/jnlp/config/Setting.java @@ -0,0 +1,176 @@ +/* Setting.java + Copyright (C) 2010 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.config; + +/** + * Represents a value for a configuration. Provides methods to get the value + * as well as marking the value as locked. + * + * Each instance of this class has an associated ValueChecker. This checker + * can be used to check if the current value is valid. The default value + * _must_ be valid. Null values can not originate externally so are (mostly) + * considered valid. + */ +public class Setting<T> { + + private String name = null; + private String description = null; + private boolean locked = false; + private ValueValidator validator = null; + private T defaultValue = null; + private T value = null; + private String source = null; + + /** + * Creates a new Settings object + * + * @param name the name of this setting + * @param description a human readable description of this setting + * @param locked whether this setting is currently locked + * @param validator the {@link ValueValidator} that can be used to validate + * the value + * @param defaultValue the default value of this setting. If this is not a + * recognized setting, use null. + * @param value the initial value of this setting + * @param source the origin of the value (a file, or perhaps "<internal>") + */ + public Setting(String name, String description, boolean locked, + ValueValidator validator, T defaultValue, T value, String source) { + this.name = name; + this.description = description; + this.locked = locked; + this.validator = validator; + this.source = source; + this.defaultValue = defaultValue; + this.value = value; + } + + /** + * Creates a new Settings object by cloning the values from another + * Settings object + * @param other a Settings object to initialize settings from + */ + public Setting(Setting<T> other) { + this(other.name, other.description, other.locked, other.validator, + other.defaultValue, other.value, other.source); + } + + /** + * @return the {@link ValueValidator} that can be used to check if + * the current value is valid + */ + public ValueValidator getValidator() { + return validator; + } + + /** + * @return the default value for this setting. May be null if this is not + * one of the supported settings + */ + public T getDefaultValue() { + return defaultValue; + } + + /** + * @return a human readable description of this setting + */ + public String getDescription() { + return description; + } + + /** + * @return the name (like foo.bar.baz) of this setting + */ + public String getName() { + return name; + } + + /** + * @return the source of the current value of this setting. May be a string + * like "internal" or it may be the location of the properties file + */ + public String getSource() { + return source; + } + + /** + * @return the current value of this setting + */ + public T getValue() { + return value; + } + + /** + * @return true if this setting is locked + */ + public boolean isLocked() { + return locked; + } + + /** + * Marks this setting as locked or unlocked. Setting the value is not + * enforced by this class. + * + * @param locked whether to mark this setting as locked or not locked. + */ + public void setLocked(boolean locked) { + this.locked = locked; + } + + /** + * Sets the source of the current value of this Setting. Maybe a string + * like "internal" or the location of the properties file + * + * @param source the source of the value + */ + public void setSource(String source) { + this.source = source; + } + + /** + * Note that setting the value is not enforced - it is the caller's + * responsibility to check if a value is locked or not before setting a + * new value + * + * @param value the new value + */ + public void setValue(T value) { + this.value = value; + } + +} diff --git a/netx/net/sourceforge/jnlp/config/ValueValidator.java b/netx/net/sourceforge/jnlp/config/ValueValidator.java new file mode 100644 index 0000000..d743e6f --- /dev/null +++ b/netx/net/sourceforge/jnlp/config/ValueValidator.java @@ -0,0 +1,66 @@ +/* ValueChecker.java + Copyright (C) 2010 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.config; + +/** + * A class implements the ValueValidator interface to indicate that it can validate + * values. + * + * @see BasicValueValidators + */ +public interface ValueValidator { + + /** + * This method checks if the given object is a valid value for this + * specific {@link ValueValidator}. Any arbitrary operation can be + * performed to ensure that the value is valid. + * + * @param value The object to validate + * @throws IllegalArgumentException if the value is invalid + */ + public void validate(Object value) throws IllegalArgumentException; + + /** + * Returns a string describing possible values in human-readable form that + * this {@link ValueValidator} accepts + * + * @return a string describing possible values that this + * {@link ValueValidator} accepts + */ + public String getPossibleValues(); +} |