- Timestamp:
- 2020-04-17T21:45:33+02:00 (5 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/PreferencesUtils.java
r14153 r16329 7 7 import java.util.Collection; 8 8 import java.util.Collections; 9 import java.util.HashMap;10 9 import java.util.Iterator; 11 10 import java.util.List; 12 11 import java.util.Map; 13 12 import java.util.Map.Entry; 14 import java.util.TreeMap; 15 16 import javax.script.ScriptEngine; 17 import javax.script.ScriptException; 13 18 14 import javax.swing.JOptionPane; 19 15 … … 30 26 /** 31 27 * 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 back33 28 * @since 12634 (extracted from {@code CustomConfigurator}) 34 29 */ … … 282 277 } 283 278 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 structures292 * @param engine - JS engine to put object293 * @param tmpPref - preferences to fill from JS294 * @param varInJS - JS variable name, where preferences are stored295 * @throws ScriptException if the evaluation fails296 */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 object376 * @param engine - JS engine to put object377 * @param tmpPref - preferences to convert378 * @param whereToPutInJS - variable name to store preferences in JS379 * @param includeDefaults - include known default values to JS objects380 * @throws ScriptException if the evaluation fails381 */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 script478 engine.eval(init);479 }480 481 279 /** 482 280 * Gets an boolean that may be specialized -
trunk/src/org/openstreetmap/josm/gui/io/CustomConfigurator.java
r15588 r16329 25 25 import java.util.regex.Pattern; 26 26 27 import javax.script.ScriptEngine;28 import javax.script.ScriptException;29 27 import javax.swing.JOptionPane; 30 28 import javax.swing.SwingUtilities; … … 386 384 private Preferences mainPrefs; 387 385 private final Map<String, Element> tasksMap = new HashMap<>(); 386 private final Map<String, String> environment = new HashMap<>(); 388 387 389 388 private boolean lastV; // last If condition result 390 391 private ScriptEngine engine;392 389 393 390 public void openAndReadXML(File file) { … … 395 392 try { 396 393 String fileDir = file.getParentFile().getAbsolutePath(); 397 if (fileDir != null) engine.eval("scriptDir='"+normalizeDirName(fileDir) +"';");394 environment.put("scriptDir", normalizeDirName(fileDir)); 398 395 try (InputStream is = Files.newInputStream(file.toPath())) { 399 396 openAndReadXML(is); 400 397 } 401 } catch ( ScriptException |IOException | SecurityException | InvalidPathException ex) {398 } catch (IOException | SecurityException | InvalidPathException ex) { 402 399 PreferencesUtils.log(ex, "Error reading custom preferences:"); 403 400 } … … 417 414 418 415 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())); 445 420 } 446 421 … … 494 469 processDeleteElement(elem); 495 470 break; 496 case "script":497 processScriptElement(elem);498 break;499 471 default: 500 472 PreferencesUtils.log("Error: Unknown element " + elementName); … … 517 489 Preferences tmpPref = readPreferencesFromDOMElement(item); 518 490 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 }530 491 531 492 if ("replace".equals(oper)) { … … 607 568 608 569 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); 614 571 } 615 572 … … 646 603 } 647 604 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 660 605 /** 661 606 * substitute ${expression} = expression evaluated by JavaScript … … 664 609 */ 665 610 private String evalVars(String s) { 666 Matcher mr = Pattern.compile("\\$\\{( [^\\}]*)\\}").matcher(s);611 Matcher mr = Pattern.compile("\\$\\{(?<identifier>[^\\}]*)\\}").matcher(s); 667 612 StringBuffer sb = new StringBuffer(); 668 613 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)); 675 617 } 676 618 mr.appendTail(sb); -
trunk/test/data/customconfigurator/append.xml
r9958 r16329 1 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 2 <config> 3 <var name="secret" value="JOSM"/> 3 4 <preferences operation="append"> 4 5 <list key="test"> 5 6 <entry value="11111111"/> 6 7 <entry value="2222222"/> 7 <entry value=" 333333333"/>8 <entry value="${secret}"/> 8 9 </list> 9 10 </preferences> -
trunk/test/unit/org/openstreetmap/josm/gui/io/CustomConfiguratorTest.java
r15716 r16329 84 84 String log = PreferencesUtils.getLog(); 85 85 assertFalse(log, log.contains("Error")); 86 assert False(Config.getPref().getList("test").isEmpty());86 assertEquals(Arrays.asList("11111111", "2222222", "JOSM"), Config.getPref().getList("test")); 87 87 88 88 // Test 2 - read(file, pref) + replace
Note:
See TracChangeset
for help on using the changeset viewer.