1 /*
   2  * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.runtime;
  27 
  28 import java.io.InputStream;
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.util.Hashtable;
  32 
  33 public class  SystemProperties {
  34    /**
  35     * JavaFX System Properties table.
  36     * First column represents javafx property name with "javafx" prefix stripped off.
  37     * Second column represents underlying runtime platform equivalent.
  38     * "jfx_specific" value in the runtime platform equivalent field indicates the property is JavaFX specific.
  39     * Empty string in   the runtime platform equivalent field indicates thete is no equivalent property for given platform.
  40     */
  41     private static final String[] sysprop_table = {
  42         /*"javafx.*/"application.codebase", "jfx_specific", /*"javafx.*/"debug", "javafx.debug"
  43     };
  44 
  45 
  46     /**
  47      * JavaFX Specific System Properties table.
  48      * First column represents javafx environment specific property name with "javafx" prefix stripped off.
  49      * Second column represents value of the property
  50     */
  51     private static final String[] jfxprop_table = {
  52         /*"javafx.*/"application.codebase", "",
  53     };
  54 
  55     private static final Hashtable sysprop_list = new Hashtable();
  56     private static final Hashtable jfxprop_list = new Hashtable();
  57 
  58     private static final String versionResourceName =
  59             "/com/sun/javafx/runtime/resources/version.properties";
  60 
  61     private static boolean isDebug;
  62 
  63     static {
  64         AccessController.doPrivileged((PrivilegedAction) () -> {
  65             addProperties (sysprop_table, false);
  66             addProperties (jfxprop_table, true);
  67             setVersions();
  68             isDebug = "true".equalsIgnoreCase(getProperty("javafx.debug"));
  69             return null;
  70         });
  71     }
  72 
  73     /*
  74      * Populate our well known version strings
  75      */
  76     private static void setVersions() {
  77         int size;
  78         InputStream is =
  79                 SystemProperties.class.getResourceAsStream(versionResourceName);
  80         try  {
  81             size = is.available();
  82 
  83             byte[] b = new byte[size];
  84             int n = is.read(b);
  85             String inStr = new String(b, "utf-8");
  86             SystemProperties.setFXProperty("javafx.version",
  87                     getValue(inStr, "release="));
  88 
  89             SystemProperties.setFXProperty("javafx.runtime.version",
  90                     getValue(inStr, "full="));
  91 
  92         } catch (Exception ignore) {
  93         }
  94     }
  95     /*
  96      * Returns a value given a name
  97      */
  98     private static String getValue(String toSearch, String name) {
  99         String s = toSearch;
 100         int index;
 101         while ((index = s.indexOf(name)) != -1) {
 102             s = s.substring(index);
 103             if ((index = s.indexOf(0x0A))!= -1) {
 104                 return (s.substring(name.length(), index)).trim();
 105             }
 106             return (s.substring(name.length(), s.length())).trim();
 107         }
 108         return "unknown";
 109     }
 110     /**
 111      * Registers a statically allocated System Properties table
 112      * Once registered properties listed in the table are availabe for inquiry through FX.getProperty().
 113      * Table is defined as a String array with JavaFX property name followed by property value or property mapping identifier
 114      * depending on whether the table contains JavaFX specific properties or not.
 115      * Note that JavaFX property names have "javafx" stripped out to optimize table lookup.
 116      * The following identifiers are available:
 117      * </p>
 118      * 1. Underlying runtime platform property name. When listed, FX.getProperty() will invoke System.getProperty()
 119      *    method to retrieve property value.
 120      *    example:
 121      *    {"version", "java.version"}
 122      * </p>
 123      * 2. "javafx_specific". When listed indicates there is no association between the property and underlying runtime
 124      *    platform. Rather the property is JavaFX specific. In that case another table needs to be provided with values
 125      *    for all JavaFX specific properties. JavaFX specific properties table is a string array containing property name
 126      *    and corresponding property value.
 127      *    example:
 128      *    {"hw.radio", "none"}
 129      * </p>
 130      * 3. Empty string. When listed, the meaning there is no association between the property and underlying runtime
 131      *    platform nor the property is JavaFX specific. FX.getProperty() invoked on that property returns null.
 132      *    example:
 133      *    {"supports.mixing", "none"}
 134      * @param table System Properties table
 135      * @param jfx_specific Indicates the table contains JavaFX specific properties
 136      */
 137     public static void addProperties (String[] table, boolean jfx_specific) {
 138         if (table == null)
 139             return;
 140 
 141         Hashtable props;
 142 
 143         if (jfx_specific) {
 144             props = jfxprop_list;
 145         } else {
 146             props = sysprop_list;
 147         }
 148 
 149         for (int i=0; i<table.length; i+=2) {
 150             props.put(table[i], table[i+1]);
 151         }
 152     }
 153 
 154     public static String getProperty (String key) {
 155         Hashtable props = sysprop_list;
 156         final String prefix = "javafx.";
 157 
 158         if (key == null)
 159                 return null;
 160 
 161         if (key.startsWith(prefix)) {
 162             key = key.substring(prefix.length());
 163         } else {
 164             return null;
 165         }
 166         final String found = (String)props.get(key);
 167         if ((found == null) || (found.equals(""))) {
 168         // No Java Runtime Environment property equivalent is found
 169             return null;
 170         }
 171 
 172 
 173         // Now check if the property is JFX specific and has no association with Runtime Environment
 174         if (found.equals("jfx_specific")) {
 175             props = jfxprop_list;
 176             return (String)props.get(key);
 177         } else {
 178             return System.getProperty(found);
 179         }
 180     }
 181 
 182    /*
 183     * Removes the property from JavaFX System Properties list
 184     * @param key JavaFX System Property name
 185     */
 186     public static void clearProperty (String key) {
 187         if (key == null)
 188                 return;
 189 
 190         Hashtable props = sysprop_list;
 191         final String prefix = "javafx.";
 192 
 193         // Remove "javafx." prefix from the key
 194         if (key.startsWith(prefix.toString())) {
 195             key = key.substring(prefix.length());
 196         } else {
 197             return;
 198         }
 199 
 200         String value = (String)props.get(key);
 201         if (value == null)
 202             return;
 203 
 204         props.remove(key);
 205 
 206         // Remove the prop from the JavaFX specific properties table if applicable
 207         if (value.equals("jfx_specific")) {
 208             props = jfxprop_list;
 209             props.remove(key);
 210         }
 211     }
 212 
 213     /**
 214      * Adds a new JavaFX specific property or modifyies existing property value.
 215      * Note that there is no method in this class to set underlying platform
 216      * property as MIDP doesn't support System.setProperty() method.
 217      * @param key JavaFX Property name
 218      * @param value Property value
 219      * @throws NullPointerException if key or value is null
 220      */
 221     public static void setFXProperty (String key, final String value) {
 222 
 223         Hashtable props = sysprop_list;
 224         final String prefix = "javafx.";
 225 
 226         // Remove "javafx." prefix from the key
 227         if (key.startsWith(prefix)) {
 228             key = key.substring(prefix.length());
 229 
 230            String k = (String)props.get(key);
 231            // Add new property to the list
 232            if (k == null) {
 233                props.put(key, "jfx_specific");
 234                props = jfxprop_list;
 235                props.put(key, value);
 236            } else if (k.equals("jfx_specific")) {
 237                // Change existing property value
 238                props = jfxprop_list;
 239                props.put(key, value);
 240                if (codebase.equals(prefix+key))
 241                    codebase_value = value;
 242            }
 243         }
 244     }
 245 
 246     public static boolean isDebug() {
 247         return isDebug;
 248     }
 249 
 250     public static String getCodebase() {
 251         return codebase_value;
 252     }
 253 
 254     public static void setCodebase(String value) {
 255          if (value == null)
 256                 value = "";
 257          codebase_value = value;
 258          setFXProperty("javafx.application.codebase", value);
 259     }
 260 
 261     private static String codebase_value;
 262 
 263     public static final String codebase = "javafx.application.codebase";
 264 }
 265