# HG changeset patch # User Jiri Vanek # Date 1545128335 -3600 # Node ID 38c1021dda36181998e67e2d39480e550f3ec8e1 # Parent 1124d07c3c506da41098015a0a7e57413621ecab deployment.config now support generic url instead just file * netx/net/sourceforge/jnlp/config/Defaults.java: added option KEY_SYSTEM_CONFIG as url and KEY_SYSTEM_CONFIG_MANDATORY as boolean, thus documented * netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java: refactored to work with general url rather then with file only * netx/net/sourceforge/jnlp/config/InfrastructureFileDescriptor.java: added (getUrl) as shortcut to getFile().toURI().toURL() * netx/net/sourceforge/jnlp/controlpanel/CommandLine.java: (CommandLine) made aware of MalformedURLException * tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java: added tests for new DeploymentConfiguration.checkUrl covering ok/not ok file, ok/not ok http * NEWS: mentioned diff -r 1124d07c3c50 -r 38c1021dda36 ChangeLog --- a/ChangeLog Tue Dec 18 11:18:13 2018 +0100 +++ b/ChangeLog Tue Dec 18 11:18:55 2018 +0100 @@ -1,3 +1,15 @@ +2018-11-28 Jiri Vanek + + deployment.config now support generic url instead just file + * netx/net/sourceforge/jnlp/config/Defaults.java: added option KEY_SYSTEM_CONFIG as url and KEY_SYSTEM_CONFIG_MANDATORY as boolean, + thus documented + * netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java: refactored to work with general url rather then with file only + * netx/net/sourceforge/jnlp/config/InfrastructureFileDescriptor.java: added (getUrl) as shortcut to getFile().toURI().toURL() + * netx/net/sourceforge/jnlp/controlpanel/CommandLine.java: (CommandLine) made aware of MalformedURLException + * tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java: added tests for new DeploymentConfiguration.checkUrl + covering ok/not ok file, ok/not ok http + * NEWS: mentioned + 2018-11-27 Jiri Vanek * netx/net/sourceforge/jnlp/OptionsDefinitions.java: (main) moved from ifelse to switch diff -r 1124d07c3c50 -r 38c1021dda36 NEWS --- a/NEWS Tue Dec 18 11:18:13 2018 +0100 +++ b/NEWS Tue Dec 18 11:18:55 2018 +0100 @@ -13,6 +13,7 @@ * --nosecurity enhanced for possibility to skip invalid signatures * enhanced to allow resources to be read also from j2se/java element (OmegaT) * PR3644 - java.lang.NoClassDefFoundError: Could not initialize class net.sourceforge.jnlp.runtime.JNLPRuntime$DeploymentConfigurationHolder +* deployment.config now support generic url instead just file New in release 1.7.1 (2017-12-15): * better work with authors file diff -r 1124d07c3c50 -r 38c1021dda36 netx/net/sourceforge/jnlp/config/Defaults.java --- a/netx/net/sourceforge/jnlp/config/Defaults.java Tue Dec 18 11:18:13 2018 +0100 +++ b/netx/net/sourceforge/jnlp/config/Defaults.java Tue Dec 18 11:18:55 2018 +0100 @@ -440,6 +440,16 @@ DeploymentConfiguration.KEY_ENABLE_MANIFEST_ATTRIBUTES_CHECK, BasicValueValidators.getManifestAttributeCheckValidator(), String.valueOf(ManifestAttributesChecker.MANIFEST_ATTRIBUTES_CHECK.ALL) + }, + { + DeploymentConfiguration.KEY_SYSTEM_CONFIG, + BasicValueValidators.getUrlValidator(), + null + }, + { + DeploymentConfiguration.KEY_SYSTEM_CONFIG_MANDATORY, + BasicValueValidators.getBooleanValidator(), + String.valueOf(false) } }; diff -r 1124d07c3c50 -r 38c1021dda36 netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java --- a/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java Tue Dec 18 11:18:13 2018 +0100 +++ b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java Tue Dec 18 11:18:55 2018 +0100 @@ -22,8 +22,9 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; -import java.io.FileReader; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.io.Reader; @@ -237,6 +238,11 @@ */ public static final String KEY_PLUGIN_JVM_ARGUMENTS= "deployment.plugin.jvm.arguments"; public static final String KEY_JRE_DIR= "deployment.jre.dir"; + /** + * remote configuration properties + */ + public static final String KEY_SYSTEM_CONFIG = "deployment.system.config"; + public static final String KEY_SYSTEM_CONFIG_MANDATORY = "deployment.system.config.mandatory"; public static final String TRANSFER_TITLE = "Legacy configuration and cache found. Those will be now transported to new locations"; @@ -255,6 +261,14 @@ currentConfiguration = Defaults.getDefaults(); } + static boolean checkUrl(URL file) { + try (InputStream s = file.openStream()) { + return true; + } catch (Throwable ex) { + // this should be logged, however, logging botle neck may not be initialised here + return false; + } + } public enum ConfigType { System, User @@ -264,7 +278,7 @@ private boolean systemPropertiesMandatory = false; /** The system's subdirResult deployment.config file */ - private File systemPropertiesFile = null; + private URL systemPropertiesFile = null; /** Source of always right and only path to file (even if underlying path changes) */ private final InfrastructureFileDescriptor userDeploymentFileDescriptor; /** The user's subdirResult deployment.config file */ @@ -301,7 +315,11 @@ * @throws ConfigurationException if it encounters a fatal error. */ public void load() throws ConfigurationException { - load(true); + try { + load(true); + } catch (MalformedURLException ex) { + throw new ConfigurationException(ex.toString()); + } } /** @@ -312,18 +330,18 @@ * resorting to the default values * @throws ConfigurationException if it encounters a fatal error. */ - public void load(boolean fixIssues) throws ConfigurationException { + public void load(boolean fixIssues) throws ConfigurationException, MalformedURLException { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkRead(userDeploymentFileDescriptor.getFullPath()); } - File systemConfigFile = findSystemConfigFile(); + URL systemConfigFile = findSystemConfigFile(); load(systemConfigFile, userDeploymentFileDescriptor.getFile(), fixIssues); } - void load(File systemConfigFile, File userFile, boolean fixIssues) throws ConfigurationException { + void load(URL systemConfigFile, File userFile, boolean fixIssues) throws ConfigurationException, MalformedURLException { Map> initialProperties = Defaults.getDefaults(); Map> systemProperties = null; @@ -357,8 +375,8 @@ * Third, read the user's subdirResult deployment.properties file */ userPropertiesFile = userFile; - Map> userProperties = loadProperties(ConfigType.User, userPropertiesFile, false); - userComments=loadComments(userPropertiesFile); + Map> userProperties = loadProperties(ConfigType.User, userPropertiesFile.toURI().toURL(), false); + userComments = loadComments(userPropertiesFile.toURI().toURL()); if (userProperties != null) { mergeMaps(initialProperties, userProperties); } @@ -499,14 +517,14 @@ /** * @return the location of system-level deployment.config file, or null if none can be found */ - private File findSystemConfigFile() { + private URL findSystemConfigFile() throws MalformedURLException { if (PathsAndFiles.ETC_DEPLOYMENT_CFG.getFile().isFile()) { - return PathsAndFiles.ETC_DEPLOYMENT_CFG.getFile(); + return PathsAndFiles.ETC_DEPLOYMENT_CFG.getUrl(); } String jrePath = null; try { - Map> tmpProperties = parsePropertiesFile(userDeploymentFileDescriptor.getFile()); + Map> tmpProperties = parsePropertiesFile(userDeploymentFileDescriptor.getUrl()); Setting jreSetting = tmpProperties.get(KEY_JRE_DIR); if (jreSetting != null) { jrePath = jreSetting.getValue(); @@ -524,7 +542,7 @@ jreFile = PathsAndFiles.JAVA_DEPLOYMENT_PROP_FILE.getFile(); } if (jreFile.isFile()) { - return jreFile; + return jreFile.toURI().toURL(); } return null; @@ -534,7 +552,7 @@ * Reads the system configuration file and sets the relevant * system-properties related variables */ - private boolean loadSystemConfiguration(File configFile) throws ConfigurationException { + private boolean loadSystemConfiguration(URL configFile) throws ConfigurationException { OutputController.getLogger().log("Loading system configuation from: " + configFile); @@ -553,26 +571,21 @@ */ String urlString = null; try { - Setting urlSettings = systemConfiguration.get("deployment.system.config"); + Setting urlSettings = systemConfiguration.get(KEY_SYSTEM_CONFIG); if (urlSettings == null || urlSettings.getValue() == null) { - OutputController.getLogger().log("No System level " + DEPLOYMENT_PROPERTIES + " found in "+configFile.getAbsolutePath()); + OutputController.getLogger().log("No System level " + DEPLOYMENT_PROPERTIES + " found in "+configFile.toExternalForm()); return false; } urlString = urlSettings.getValue(); - Setting mandatory = systemConfiguration.get("deployment.system.config.mandatory"); + Setting mandatory = systemConfiguration.get(KEY_SYSTEM_CONFIG_MANDATORY); systemPropertiesMandatory = Boolean.valueOf(mandatory == null ? null : mandatory.getValue()); //never null OutputController.getLogger().log("System level settings " + DEPLOYMENT_PROPERTIES + " are mandatory:" + systemPropertiesMandatory); URL url = new URL(urlString); - if (url.getProtocol().equals("file")) { - systemPropertiesFile = new File(url.getFile()); - OutputController.getLogger().log("Using System level" + DEPLOYMENT_PROPERTIES + ": " + systemPropertiesFile); - return true; - } else { - OutputController.getLogger().log("Remote + " + DEPLOYMENT_PROPERTIES + " not supported: " + urlString + "in " + configFile.getAbsolutePath()); - return false; - } + systemPropertiesFile = url; + OutputController.getLogger().log("Using System level" + DEPLOYMENT_PROPERTIES + ": " + systemPropertiesFile); + return true; } catch (MalformedURLException e) { - OutputController.getLogger().log("Invalid url for " + DEPLOYMENT_PROPERTIES+ ": " + urlString + "in " + configFile.getAbsolutePath()); + OutputController.getLogger().log("Invalid url for " + DEPLOYMENT_PROPERTIES+ ": " + urlString + "in " + configFile.toExternalForm()); OutputController.getLogger().log(e); if (systemPropertiesMandatory){ ConfigurationException ce = new ConfigurationException("Invalid url to system properties, which are mandatory"); @@ -593,9 +606,9 @@ * * @throws ConfigurationException if the file is mandatory but cannot be read */ - private Map> loadProperties(ConfigType type, File file, boolean mandatory) + private Map> loadProperties(ConfigType type, URL file, boolean mandatory) throws ConfigurationException { - if (file == null || !file.isFile()) { + if (file == null || !checkUrl(file)) { OutputController.getLogger().log("No " + type.toString() + " level " + DEPLOYMENT_PROPERTIES + " found."); if (!mandatory) { return null; @@ -684,12 +697,12 @@ * @param propertiesFile the file to read Properties from * @throws IOException if an IO problem occurs */ - private Map> parsePropertiesFile(File propertiesFile) throws IOException { + private Map> parsePropertiesFile(URL propertiesFile) throws IOException { Map> result = new HashMap<>(); Properties properties = new Properties(); - try (Reader reader = new BufferedReader(new FileReader(propertiesFile))) { + try (Reader reader = new BufferedReader(new InputStreamReader(propertiesFile.openStream(), "UTF-8"))) { properties.load(reader); } @@ -904,9 +917,9 @@ //standard date.toString format public static final SimpleDateFormat pattern = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); - private static String loadComments(File path) { + private static String loadComments(URL path) { StringBuilder r = new StringBuilder(); - try (BufferedReader br = new BufferedReader(new FileReader(path))) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(path.openStream(), "UTF-8"))) { while (true) { String s = br.readLine(); if (s == null) { diff -r 1124d07c3c50 -r 38c1021dda36 netx/net/sourceforge/jnlp/config/InfrastructureFileDescriptor.java --- a/netx/net/sourceforge/jnlp/config/InfrastructureFileDescriptor.java Tue Dec 18 11:18:13 2018 +0100 +++ b/netx/net/sourceforge/jnlp/config/InfrastructureFileDescriptor.java Tue Dec 18 11:18:55 2018 +0100 @@ -38,6 +38,8 @@ package net.sourceforge.jnlp.config; import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; import net.sourceforge.jnlp.runtime.JNLPRuntime; import net.sourceforge.jnlp.runtime.Translator; @@ -75,6 +77,10 @@ public File getFile() { return new File(getFullPath()); } + + public URL getUrl() throws MalformedURLException { + return getFile().toURI().toURL(); + } public void setValue(String value) { setValue(value, JNLPRuntime.getConfiguration()); diff -r 1124d07c3c50 -r 38c1021dda36 netx/net/sourceforge/jnlp/controlpanel/CommandLine.java --- a/netx/net/sourceforge/jnlp/controlpanel/CommandLine.java Tue Dec 18 11:18:13 2018 +0100 +++ b/netx/net/sourceforge/jnlp/controlpanel/CommandLine.java Tue Dec 18 11:18:55 2018 +0100 @@ -21,6 +21,7 @@ import static net.sourceforge.jnlp.runtime.Translator.R; import java.io.IOException; +import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -86,7 +87,7 @@ config = new DeploymentConfiguration(); try { config.load(false); - } catch (ConfigurationException e) { + } catch (ConfigurationException | MalformedURLException e) { OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, R("RConfigurationFatal")); OutputController.getLogger().log(e); } diff -r 1124d07c3c50 -r 38c1021dda36 tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java --- a/tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java Tue Dec 18 11:18:13 2018 +0100 +++ b/tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java Tue Dec 18 11:18:55 2018 +0100 @@ -33,12 +33,12 @@ 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.io.IOException; +import java.net.URL; import java.util.Date; import static org.junit.Assert.assertTrue; @@ -46,13 +46,16 @@ import javax.naming.ConfigurationException; import net.sourceforge.jnlp.PluginBridgeTest; +import net.sourceforge.jnlp.ServerAccess; +import net.sourceforge.jnlp.ServerLauncher; +import net.sourceforge.jnlp.annotations.Remote; import net.sourceforge.jnlp.util.FileUtils; import net.sourceforge.jnlp.util.logging.NoStdOutErrTest; import org.junit.Assert; import org.junit.Test; -public class DeploymentConfigurationTest extends NoStdOutErrTest{ +public class DeploymentConfigurationTest extends NoStdOutErrTest { @Test public void testLoad() throws ConfigurationException { @@ -73,34 +76,34 @@ Properties target = new Properties(); config.copyTo(target); - assertTrue(target.size() != 0); + assertTrue(!target.isEmpty()); } - + @Test public void testPersistedComments() throws ConfigurationException, IOException { final File f = File.createTempFile("proeprties", "withComments"); f.deleteOnExit(); FileUtils.saveFile("#commented1=val1\nproeprty2=val2\n#commented3=val3\nproeprty4=val4", f); - DeploymentConfiguration dc = new DeploymentConfiguration(new InfrastructureFileDescriptor(){ - + DeploymentConfiguration dc = new DeploymentConfiguration(new InfrastructureFileDescriptor() { + @Override public String getFullPath() { return f.getAbsolutePath(); } - + }); dc.load(); Assert.assertEquals("val2", dc.getProperty("proeprty2")); Assert.assertEquals("val4", dc.getProperty("proeprty4")); Assert.assertEquals(null, dc.getProperty("commented1")); Assert.assertEquals(null, dc.getProperty("commented3")); - + dc.save(); - + String s = FileUtils.loadFileAsString(f); - Assert.assertTrue(s.contains("#"+DeploymentConfiguration.DEPLOYMENT_COMMENT)); + Assert.assertTrue(s.contains("#" + DeploymentConfiguration.DEPLOYMENT_COMMENT)); String date = new Date().toString().substring(0, 10); //every propertiews file have header and date by default - Assert.assertTrue(s.contains("#"+date)); //check day part of date... + Assert.assertTrue(s.contains("#" + date)); //check day part of date... Assert.assertTrue(s.contains("#commented1")); Assert.assertTrue(s.contains("proeprty2")); Assert.assertTrue(s.contains("#commented3")); @@ -109,11 +112,9 @@ Assert.assertTrue(s.contains("val2")); Assert.assertTrue(s.contains("val3")); Assert.assertTrue(s.contains("val4")); - - } - - - + + } + @Test public void testEnsurePersistedCommentsDoNotMultiplyHeaderAndDate() throws ConfigurationException, IOException { final File f = File.createTempFile("proeprties", "withComments"); @@ -159,4 +160,89 @@ //System.out.println(s); } + @Test + public void testCheckUrlFileOk() throws ConfigurationException, IOException { + File f = File.createTempFile("itw", "checkUrlTest"); + f.deleteOnExit(); + boolean is = DeploymentConfiguration.checkUrl(f.toURI().toURL()); + Assert.assertTrue("File was supposed to exists", is); + boolean is2 = DeploymentConfiguration.checkUrl(f.toURI().toURL()); + Assert.assertTrue("File was supposed to exists", is2); + } + + @Test + public void testCheckUrlFileNotOk() throws ConfigurationException, IOException { + File f = new File("/some/not/existing/file"); + boolean is = DeploymentConfiguration.checkUrl(f.toURI().toURL()); + Assert.assertFalse("File was NOT supposed to exists", is); + boolean is2 = DeploymentConfiguration.checkUrl(f.toURI().toURL()); + Assert.assertFalse("File was NOT supposed to exists", is2); + } + + @Test + public void testCheckUrlFileOkNotOk() throws ConfigurationException, IOException { + File f = File.createTempFile("itw", "checkUrlTest"); + f.deleteOnExit(); + boolean is = DeploymentConfiguration.checkUrl(f.toURI().toURL()); + Assert.assertTrue("File was supposed to exists", is); + f.delete(); + boolean is2 = DeploymentConfiguration.checkUrl(f.toURI().toURL()); + Assert.assertFalse("File was NOT supposed to exists", is2); + f.createNewFile(); + f.deleteOnExit(); + boolean is3 = DeploymentConfiguration.checkUrl(f.toURI().toURL()); + Assert.assertTrue("File was supposed to exists", is3); + } + + @Test + public void testCheckUrlRemoteNotOk() throws ConfigurationException, IOException { + boolean is = DeploymentConfiguration.checkUrl(new URL("http://some.not/surely/existing.file")); + Assert.assertFalse("File was supposed to not exists", is); + } + + @Test + public void testCheckUrlRemoteNotOk404_1() throws ConfigurationException, IOException { + ServerLauncher server = ServerAccess.getIndependentInstance(System.getProperty("java.io.tmpdir"), ServerAccess.findFreePort()); + File f = File.createTempFile("itw", "checkUrlTest"); + f.delete(); + f.mkdir(); + f.deleteOnExit(); + try { + URL u = new URL("http://localhost:" + server.getPort() + "/" + f.getName() + "/notexisting.file"); + boolean is = DeploymentConfiguration.checkUrl(u); + Assert.assertFalse("File was not supposed to exists", is); + } finally { + server.stop(); + } + } + + @Test + @Remote + public void testCheckUrlRemoteNotOk404_2() throws ConfigurationException, IOException { + URL u = new URL("https://google.com/some/not/existingitw.file"); + boolean is = DeploymentConfiguration.checkUrl(u); + Assert.assertFalse("File was not supposed to exists", is); + } + + @Test + public void testCheckUrlRemoteOk() throws ConfigurationException, IOException { + ServerLauncher server = ServerAccess.getIndependentInstance(System.getProperty("java.io.tmpdir"), ServerAccess.findFreePort()); + try { + File f = File.createTempFile("itw", "checkUrlTest"); + f.deleteOnExit(); + URL u = new URL("http://localhost:" + server.getPort() + "/" + f.getName()); + boolean is = DeploymentConfiguration.checkUrl(u); + Assert.assertTrue("File was supposed to exists", is); + f.delete(); + //404_3 + boolean is2 = DeploymentConfiguration.checkUrl(u); + Assert.assertFalse("File was NOT supposed to exists", is2); + f.createNewFile(); + f.deleteOnExit(); + boolean is3 = DeploymentConfiguration.checkUrl(u); + Assert.assertTrue("File was supposed to exists", is3); + } finally { + server.stop(); + } + } }