Changeset 16329 in josm


Ignore:
Timestamp:
2020-04-17T21:45:33+02:00 (17 months ago)
Author:
simon04
Message:

fix #18830 - Remove PreferencesUtils#readPrefsFromJS due to Nashorn removal

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/PreferencesUtils.java

    r14153 r16329  
    77import java.util.Collection;
    88import java.util.Collections;
    9 import java.util.HashMap;
    109import java.util.Iterator;
    1110import java.util.List;
    1211import java.util.Map;
    1312import java.util.Map.Entry;
    14 import java.util.TreeMap;
    15 
    16 import javax.script.ScriptEngine;
    17 import javax.script.ScriptException;
     13
    1814import javax.swing.JOptionPane;
    1915
     
    3026/**
    3127 * Helper class to do specific Preferences operation - appending, replacing, deletion by key and by value
    32  * Also contains functions that convert preferences object to JavaScript object and back
    3328 * @since 12634 (extracted from {@code CustomConfigurator})
    3429 */
     
    282277    }
    283278
    284     public static void modifyPreferencesByScript(ScriptEngine engine, Preferences tmpPref, String js) throws ScriptException {
    285         loadPrefsToJS(engine, tmpPref, "API.pref", true);
    286         engine.eval(js);
    287         readPrefsFromJS(engine, tmpPref, "API.pref");
    288     }
    289 
    290     /**
    291      * Convert JavaScript preferences object to preferences data structures
    292      * @param engine - JS engine to put object
    293      * @param tmpPref - preferences to fill from JS
    294      * @param varInJS - JS variable name, where preferences are stored
    295      * @throws ScriptException if the evaluation fails
    296      */
    297     public static void readPrefsFromJS(ScriptEngine engine, Preferences tmpPref, String varInJS) throws ScriptException {
    298         String finish =
    299             "stringMap = new java.util.TreeMap ;"+
    300             "listMap =  new java.util.TreeMap ;"+
    301             "listlistMap = new java.util.TreeMap ;"+
    302             "listmapMap =  new java.util.TreeMap ;"+
    303             "for (key in "+varInJS+") {"+
    304             "  val = "+varInJS+"[key];"+
    305             "  type = typeof val == 'string' ? 'string' : val.type;"+
    306             "  if (type == 'string') {"+
    307             "    stringMap.put(key, val);"+
    308             "  } else if (type == 'list') {"+
    309             "    l = new java.util.ArrayList;"+
    310             "    for (i=0; i<val.length; i++) {"+
    311             "      l.add(java.lang.String.valueOf(val[i]));"+
    312             "    }"+
    313             "    listMap.put(key, l);"+
    314             "  } else if (type == 'listlist') {"+
    315             "    l = new java.util.ArrayList;"+
    316             "    for (i=0; i<val.length; i++) {"+
    317             "      list=val[i];"+
    318             "      jlist=new java.util.ArrayList;"+
    319             "      for (j=0; j<list.length; j++) {"+
    320             "         jlist.add(java.lang.String.valueOf(list[j]));"+
    321             "      }"+
    322             "      l.add(jlist);"+
    323             "    }"+
    324             "    listlistMap.put(key, l);"+
    325             "  } else if (type == 'listmap') {"+
    326             "    l = new java.util.ArrayList;"+
    327             "    for (i=0; i<val.length; i++) {"+
    328             "      map=val[i];"+
    329             "      jmap=new java.util.TreeMap;"+
    330             "      for (var key2 in map) {"+
    331             "         jmap.put(key2,java.lang.String.valueOf(map[key2]));"+
    332             "      }"+
    333             "      l.add(jmap);"+
    334             "    }"+
    335             "    listmapMap.put(key, l);"+
    336             "  }  else {" +
    337             "   " + PreferencesUtils.class.getName() + ".log('Unknown type:'+val.type+ '- use list, listlist or listmap'); }"+
    338             "  }";
    339         engine.eval(finish);
    340 
    341         @SuppressWarnings("unchecked")
    342         Map<String, String> stringMap = (Map<String, String>) engine.get("stringMap");
    343         @SuppressWarnings("unchecked")
    344         Map<String, List<String>> listMap = (Map<String, List<String>>) engine.get("listMap");
    345         @SuppressWarnings("unchecked")
    346         Map<String, List<Collection<String>>> listlistMap = (Map<String, List<Collection<String>>>) engine.get("listlistMap");
    347         @SuppressWarnings("unchecked")
    348         Map<String, List<Map<String, String>>> listmapMap = (Map<String, List<Map<String, String>>>) engine.get("listmapMap");
    349 
    350         tmpPref.settingsMap.clear();
    351 
    352         Map<String, Setting<?>> tmp = new HashMap<>();
    353         for (Entry<String, String> e : stringMap.entrySet()) {
    354             tmp.put(e.getKey(), new StringSetting(e.getValue()));
    355         }
    356         for (Entry<String, List<String>> e : listMap.entrySet()) {
    357             tmp.put(e.getKey(), new ListSetting(e.getValue()));
    358         }
    359 
    360         for (Entry<String, List<Collection<String>>> e : listlistMap.entrySet()) {
    361             @SuppressWarnings({ "unchecked", "rawtypes" })
    362             List<List<String>> value = (List) e.getValue();
    363             tmp.put(e.getKey(), new ListListSetting(value));
    364         }
    365         for (Entry<String, List<Map<String, String>>> e : listmapMap.entrySet()) {
    366             tmp.put(e.getKey(), new MapListSetting(e.getValue()));
    367         }
    368         for (Entry<String, Setting<?>> e : tmp.entrySet()) {
    369             if (e.getValue().equals(tmpPref.defaultsMap.get(e.getKey()))) continue;
    370             tmpPref.settingsMap.put(e.getKey(), e.getValue());
    371         }
    372     }
    373 
    374     /**
    375      * Convert preferences data structures to JavaScript object
    376      * @param engine - JS engine to put object
    377      * @param tmpPref - preferences to convert
    378      * @param whereToPutInJS - variable name to store preferences in JS
    379      * @param includeDefaults - include known default values to JS objects
    380      * @throws ScriptException if the evaluation fails
    381      */
    382     public static void loadPrefsToJS(ScriptEngine engine, Preferences tmpPref, String whereToPutInJS, boolean includeDefaults)
    383             throws ScriptException {
    384         Map<String, String> stringMap = new TreeMap<>();
    385         Map<String, List<String>> listMap = new TreeMap<>();
    386         Map<String, List<List<String>>> listlistMap = new TreeMap<>();
    387         Map<String, List<Map<String, String>>> listmapMap = new TreeMap<>();
    388 
    389         if (includeDefaults) {
    390             for (Map.Entry<String, Setting<?>> e: tmpPref.defaultsMap.entrySet()) {
    391                 Setting<?> setting = e.getValue();
    392                 if (setting instanceof StringSetting) {
    393                     stringMap.put(e.getKey(), ((StringSetting) setting).getValue());
    394                 } else if (setting instanceof ListSetting) {
    395                     listMap.put(e.getKey(), ((ListSetting) setting).getValue());
    396                 } else if (setting instanceof ListListSetting) {
    397                     listlistMap.put(e.getKey(), ((ListListSetting) setting).getValue());
    398                 } else if (setting instanceof MapListSetting) {
    399                     listmapMap.put(e.getKey(), ((MapListSetting) setting).getValue());
    400                 }
    401             }
    402         }
    403         tmpPref.settingsMap.entrySet().removeIf(e -> e.getValue().getValue() == null);
    404 
    405         for (Map.Entry<String, Setting<?>> e: tmpPref.settingsMap.entrySet()) {
    406             Setting<?> setting = e.getValue();
    407             if (setting instanceof StringSetting) {
    408                 stringMap.put(e.getKey(), ((StringSetting) setting).getValue());
    409             } else if (setting instanceof ListSetting) {
    410                 listMap.put(e.getKey(), ((ListSetting) setting).getValue());
    411             } else if (setting instanceof ListListSetting) {
    412                 listlistMap.put(e.getKey(), ((ListListSetting) setting).getValue());
    413             } else if (setting instanceof MapListSetting) {
    414                 listmapMap.put(e.getKey(), ((MapListSetting) setting).getValue());
    415             }
    416         }
    417 
    418         engine.put("stringMap", stringMap);
    419         engine.put("listMap", listMap);
    420         engine.put("listlistMap", listlistMap);
    421         engine.put("listmapMap", listmapMap);
    422 
    423         String init =
    424             "function getJSList( javaList ) {"+
    425             " var jsList; var i; "+
    426             " if (javaList == null) return null;"+
    427             "jsList = [];"+
    428             "  for (i = 0; i < javaList.size(); i++) {"+
    429             "    jsList.push(String(list.get(i)));"+
    430             "  }"+
    431             "return jsList;"+
    432             "}"+
    433             "function getJSMap( javaMap ) {"+
    434             " var jsMap; var it; var e; "+
    435             " if (javaMap == null) return null;"+
    436             " jsMap = {};"+
    437             " for (it = javaMap.entrySet().iterator(); it.hasNext();) {"+
    438             "    e = it.next();"+
    439             "    jsMap[ String(e.getKey()) ] = String(e.getValue()); "+
    440             "  }"+
    441             "  return jsMap;"+
    442             "}"+
    443             "for (it = stringMap.entrySet().iterator(); it.hasNext();) {"+
    444             "  e = it.next();"+
    445             whereToPutInJS+"[String(e.getKey())] = String(e.getValue());"+
    446             "}\n"+
    447             "for (it = listMap.entrySet().iterator(); it.hasNext();) {"+
    448             "  e = it.next();"+
    449             "  list = e.getValue();"+
    450             "  jslist = getJSList(list);"+
    451             "  jslist.type = 'list';"+
    452             whereToPutInJS+"[String(e.getKey())] = jslist;"+
    453             "}\n"+
    454             "for (it = listlistMap.entrySet().iterator(); it.hasNext(); ) {"+
    455             "  e = it.next();"+
    456             "  listlist = e.getValue();"+
    457             "  jslistlist = [];"+
    458             "  for (it2 = listlist.iterator(); it2.hasNext(); ) {"+
    459             "    list = it2.next(); "+
    460             "    jslistlist.push(getJSList(list));"+
    461             "    }"+
    462             "  jslistlist.type = 'listlist';"+
    463             whereToPutInJS+"[String(e.getKey())] = jslistlist;"+
    464             "}\n"+
    465             "for (it = listmapMap.entrySet().iterator(); it.hasNext();) {"+
    466             "  e = it.next();"+
    467             "  listmap = e.getValue();"+
    468             "  jslistmap = [];"+
    469             "  for (it2 = listmap.iterator(); it2.hasNext();) {"+
    470             "    map = it2.next();"+
    471             "    jslistmap.push(getJSMap(map));"+
    472             "    }"+
    473             "  jslistmap.type = 'listmap';"+
    474             whereToPutInJS+"[String(e.getKey())] = jslistmap;"+
    475             "}\n";
    476 
    477         // Execute conversion script
    478         engine.eval(init);
    479     }
    480 
    481279    /**
    482280     * Gets an boolean that may be specialized
  • trunk/src/org/openstreetmap/josm/gui/io/CustomConfigurator.java

    r15588 r16329  
    2525import java.util.regex.Pattern;
    2626
    27 import javax.script.ScriptEngine;
    28 import javax.script.ScriptException;
    2927import javax.swing.JOptionPane;
    3028import javax.swing.SwingUtilities;
     
    386384        private Preferences mainPrefs;
    387385        private final Map<String, Element> tasksMap = new HashMap<>();
     386        private final Map<String, String> environment = new HashMap<>();
    388387
    389388        private boolean lastV; // last If condition result
    390 
    391         private ScriptEngine engine;
    392389
    393390        public void openAndReadXML(File file) {
     
    395392            try {
    396393                String fileDir = file.getParentFile().getAbsolutePath();
    397                 if (fileDir != null) engine.eval("scriptDir='"+normalizeDirName(fileDir) +"';");
     394                environment.put("scriptDir", normalizeDirName(fileDir));
    398395                try (InputStream is = Files.newInputStream(file.toPath())) {
    399396                    openAndReadXML(is);
    400397                }
    401             } catch (ScriptException | IOException | SecurityException | InvalidPathException ex) {
     398            } catch (IOException | SecurityException | InvalidPathException ex) {
    402399                PreferencesUtils.log(ex, "Error reading custom preferences:");
    403400            }
     
    417414
    418415        public XMLCommandProcessor(Preferences mainPrefs) {
    419             try {
    420                 this.mainPrefs = mainPrefs;
    421                 PreferencesUtils.resetLog();
    422                 engine = Utils.getJavaScriptEngine();
    423                 if (engine == null) {
    424                     throw new ScriptException("Failed to retrieve JavaScript engine");
    425                 }
    426                 engine.eval("API={}; API.pref={}; API.fragments={};");
    427 
    428                 engine.eval("homeDir='"+normalizeDirName(Config.getDirs().getPreferencesDirectory(false).getAbsolutePath()) +"';");
    429                 engine.eval("josmVersion="+Version.getInstance().getVersion()+';');
    430                 String className = CustomConfigurator.class.getName();
    431                 engine.eval("API.messageBox="+className+".messageBox");
    432                 engine.eval("API.askText=function(text) { return String("+className+".askForText(text));}");
    433                 engine.eval("API.askOption="+className+".askForOption");
    434                 engine.eval("API.downloadFile="+className+".downloadFile");
    435                 engine.eval("API.downloadAndUnpackFile="+className+".downloadAndUnpackFile");
    436                 engine.eval("API.deleteFile="+className+".deleteFile");
    437                 engine.eval("API.plugin ="+className+".pluginOperation");
    438                 engine.eval("API.pluginInstall = function(names) { "+className+".pluginOperation(names,'','');}");
    439                 engine.eval("API.pluginUninstall = function(names) { "+className+".pluginOperation('',names,'');}");
    440                 engine.eval("API.pluginDelete = function(names) { "+className+".pluginOperation('','',names);}");
    441             } catch (ScriptException ex) {
    442                 PreferencesUtils.log("Error: initializing script engine: "+ex.getMessage());
    443                 Logging.error(ex);
    444             }
     416            this.mainPrefs = mainPrefs;
     417            PreferencesUtils.resetLog();
     418            setVar("homeDir", normalizeDirName(Config.getDirs().getPreferencesDirectory(false).getAbsolutePath()));
     419            setVar("josmVersion", String.valueOf(Version.getInstance().getVersion()));
    445420        }
    446421
     
    494469                    processDeleteElement(elem);
    495470                    break;
    496                 case "script":
    497                     processScriptElement(elem);
    498                     break;
    499471                default:
    500472                    PreferencesUtils.log("Error: Unknown element " + elementName);
     
    517489            Preferences tmpPref = readPreferencesFromDOMElement(item);
    518490            PreferencesUtils.showPrefs(tmpPref);
    519 
    520             if (!id.isEmpty()) {
    521                 try {
    522                     String fragmentVar = "API.fragments['"+id+"']";
    523                     engine.eval(fragmentVar+"={};");
    524                     PreferencesUtils.loadPrefsToJS(engine, tmpPref, fragmentVar, false);
    525                     // we store this fragment as API.fragments['id']
    526                 } catch (ScriptException ex) {
    527                     PreferencesUtils.log(ex, "Error: can not load preferences fragment:");
    528                 }
    529             }
    530491
    531492            if ("replace".equals(oper)) {
     
    607568
    608569        public void setVar(String name, String value) {
    609             try {
    610                 engine.eval(name+"='"+value+"';");
    611             } catch (ScriptException ex) {
    612                 PreferencesUtils.log(ex, String.format("Error: Can not assign variable: %s=%s :", name, value));
    613             }
     570            environment.put(name, value);
    614571        }
    615572
     
    646603        }
    647604
    648         private void processScriptElement(Element elem) {
    649             String js = elem.getChildNodes().item(0).getTextContent();
    650             PreferencesUtils.log("Processing script...");
    651             try {
    652                 PreferencesUtils.modifyPreferencesByScript(engine, mainPrefs, js);
    653             } catch (ScriptException ex) {
    654                 messageBox("e", ex.getMessage());
    655                 PreferencesUtils.log(ex, "JS error:");
    656             }
    657             PreferencesUtils.log("Script finished");
    658         }
    659 
    660605        /**
    661606         * substitute ${expression} = expression evaluated by JavaScript
     
    664609         */
    665610        private String evalVars(String s) {
    666             Matcher mr = Pattern.compile("\\$\\{([^\\}]*)\\}").matcher(s);
     611            Matcher mr = Pattern.compile("\\$\\{(?<identifier>[^\\}]*)\\}").matcher(s);
    667612            StringBuffer sb = new StringBuffer();
    668613            while (mr.find()) {
    669                 try {
    670                     String result = engine.eval(mr.group(1)).toString();
    671                     mr.appendReplacement(sb, result);
    672                 } catch (ScriptException ex) {
    673                     PreferencesUtils.log(ex, String.format("Error: Can not evaluate expression %s :", mr.group(1)));
    674                 }
     614                String identifier = mr.group("identifier");
     615                String value = environment.get(identifier);
     616                mr.appendReplacement(sb, String.valueOf(value));
    675617            }
    676618            mr.appendTail(sb);
  • trunk/test/data/customconfigurator/append.xml

    r9958 r16329  
    11<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    22<config>
     3<var name="secret" value="JOSM"/>
    34<preferences operation="append">
    45<list key="test">
    56    <entry value="11111111"/>
    67    <entry value="2222222"/>
    7     <entry value="333333333"/>
     8    <entry value="${secret}"/>
    89  </list>
    910</preferences>
  • trunk/test/unit/org/openstreetmap/josm/gui/io/CustomConfiguratorTest.java

    r15716 r16329  
    8484        String log = PreferencesUtils.getLog();
    8585        assertFalse(log, log.contains("Error"));
    86         assertFalse(Config.getPref().getList("test").isEmpty());
     86        assertEquals(Arrays.asList("11111111", "2222222", "JOSM"), Config.getPref().getList("test"));
    8787
    8888        // Test 2 - read(file, pref) + replace
Note: See TracChangeset for help on using the changeset viewer.