EditObject.java revision 1385:a5a67511b22b
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
26package jdk.nashorn.tools.jjs;
27
28import java.util.Collections;
29import java.util.HashSet;
30import java.util.Set;
31import java.util.function.Consumer;
32import jdk.nashorn.api.scripting.AbstractJSObject;
33import jdk.nashorn.internal.runtime.JSType;
34import 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 */
40final 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}
129