changeset 1507:38c1021dda36

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
author Jiri Vanek <jvanek@redhat.com>
date Tue, 18 Dec 2018 11:18:55 +0100
parents 1124d07c3c50
children 0c8e7d6eff33
files ChangeLog NEWS netx/net/sourceforge/jnlp/config/Defaults.java netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java netx/net/sourceforge/jnlp/config/InfrastructureFileDescriptor.java netx/net/sourceforge/jnlp/controlpanel/CommandLine.java tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java
diffstat 7 files changed, 178 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- 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 <jvanek@redhat.com>
+
+	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 <jvanek@redhat.com>
 
 	* netx/net/sourceforge/jnlp/OptionsDefinitions.java: (main) moved from ifelse to switch
--- 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
--- 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)
                 }
         };
 
--- 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<String, Setting<String>> initialProperties = Defaults.getDefaults();
 
         Map<String, Setting<String>> systemProperties = null;
@@ -357,8 +375,8 @@
          * Third, read the user's subdirResult deployment.properties file
          */
         userPropertiesFile = userFile;
-        Map<String, Setting<String>> userProperties = loadProperties(ConfigType.User, userPropertiesFile, false);
-        userComments=loadComments(userPropertiesFile);
+        Map<String, Setting<String>> 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<String, Setting<String>> tmpProperties = parsePropertiesFile(userDeploymentFileDescriptor.getFile());
+            Map<String, Setting<String>> tmpProperties = parsePropertiesFile(userDeploymentFileDescriptor.getUrl());
             Setting<String> 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<String> urlSettings = systemConfiguration.get("deployment.system.config");
+            Setting<String> 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<String> mandatory = systemConfiguration.get("deployment.system.config.mandatory");
+            Setting<String> 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<String, Setting<String>> loadProperties(ConfigType type, File file, boolean mandatory)
+    private Map<String, Setting<String>> 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<String, Setting<String>> parsePropertiesFile(File propertiesFile) throws IOException {
+    private Map<String, Setting<String>> parsePropertiesFile(URL propertiesFile) throws IOException {
         Map<String, Setting<String>> 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) {
--- 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());
--- 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);
         }
--- 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();
+        }
+    }
 }