1 /* 2 * Copyright (c) 2015, 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 jdk.nashorn.tools.jjs; 27 28 import java.util.Collections; 29 import java.util.HashSet; 30 import java.util.Set; 31 import java.util.function.Consumer; 32 import jdk.nashorn.api.scripting.AbstractJSObject; 33 import jdk.nashorn.internal.runtime.JSType; 34 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 35 36 /* 37 * "edit" top level script function which shows an external Window 38 * for editing and evaluating scripts from it. 39 */ 40 final class EditObject extends AbstractJSObject { 41 private static final Set<String> props; 42 static { 43 final HashSet<String> s = new HashSet<>(); 44 s.add("editor"); 45 props = Collections.unmodifiableSet(s); 46 } 47 48 private final Consumer<String> errorHandler; 49 private final Consumer<String> evaluator; 50 private final Console console; 51 private String editor; 52 53 EditObject(final Consumer<String> errorHandler, final Consumer<String> evaluator, 54 final Console console) { 55 this.errorHandler = errorHandler; 56 this.evaluator = evaluator; 57 this.console = console; 58 } 59 60 @Override 61 public Object getDefaultValue(final Class<?> hint) { 62 if (hint == String.class) { 63 return toString(); 64 } 65 return UNDEFINED; 66 } 67 68 @Override 69 public String toString() { 70 return "function edit() { [native code] }"; 71 } 72 73 @Override 74 public Set<String> keySet() { 75 return props; 76 } 77 78 @Override 79 public Object getMember(final String name) { 80 if (name.equals("editor")) { 81 return editor; 82 } 83 return UNDEFINED; 84 } 85 86 @Override 87 public void setMember(final String name, final Object value) { 88 if (name.equals("editor")) { 89 this.editor = JSType.toString(value); 90 } 91 } 92 93 // called whenever user 'saves' script in editor 94 class SaveHandler implements Consumer<String> { 95 private String lastStr; // last seen code 96 97 SaveHandler(final String str) { 98 this.lastStr = str; 99 } 100 101 @Override 102 public void accept(final String str) { 103 // ignore repeated save of the same code! 104 if (! str.equals(lastStr)) { 105 this.lastStr = str; 106 // evaluate the new code 107 evaluator.accept(str); 108 } 109 } 110 } 111 112 @Override 113 public Object call(final Object thiz, final Object... args) { 114 final String initText = args.length > 0? JSType.toString(args[0]) : ""; 115 final SaveHandler saveHandler = new SaveHandler(initText); 116 if (editor != null && !editor.isEmpty()) { 117 ExternalEditor.edit(editor, errorHandler, initText, saveHandler, console); 118 } else { 119 EditPad.edit(errorHandler, initText, saveHandler); 120 } 121 return UNDEFINED; 122 } 123 124 @Override 125 public boolean isFunction() { 126 return true; 127 } 128 }