1/*
2 * Copyright (c) 2006, 2016, 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 netscape.javascript;
27
28import jdk.internal.netscape.javascript.spi.JSObjectProvider;
29import java.applet.Applet;
30import java.security.AccessController;
31import java.security.PrivilegedAction;
32import java.util.Iterator;
33import java.util.ServiceLoader;
34
35/**
36 * <p>
37 * Allows Java code to manipulate JavaScript objects.
38 * </p>
39 *
40 * <p>
41 * When a JavaScript object is passed or returned to Java code, it
42 * is wrapped in an instance of {@code JSObject}. When a
43 * {@code JSObject} instance is passed to the JavaScript engine,
44 * it is unwrapped back to its original JavaScript object. The
45 * {@code JSObject} class provides a way to invoke JavaScript
46 * methods and examine JavaScript properties.
47 * </p>
48 *
49 * <p> Any data returned from the JavaScript engine to Java is
50 * converted to Java data types. Certain data passed to the JavaScript
51 * engine is converted to JavaScript data types.
52 * </p>
53 *
54 */
55@SuppressWarnings("deprecation")
56public abstract class JSObject {
57    /**
58     * Constructs a new JSObject. Users should neither call this method nor
59     * subclass JSObject.
60     */
61    protected JSObject()  {
62    }
63
64    /**
65     * Calls a JavaScript method. Equivalent to
66     * "this.methodName(args[0], args[1], ...)" in JavaScript.
67     *
68     * @param methodName The name of the JavaScript method to be invoked.
69     * @param args the Java objects passed as arguments to the method.
70     * @return Result of the method.
71     * @throws JSException when an error is reported from the browser or
72     * JavaScript engine.
73     */
74    public abstract Object call(String methodName, Object... args) throws JSException;
75
76    /**
77     * Evaluates a JavaScript expression. The expression is a string of
78     * JavaScript source code which will be evaluated in the context given by
79     * "this".
80     *
81     * @param s The JavaScript expression.
82     * @return Result of the JavaScript evaluation.
83     * @throws JSException when an error is reported from the browser or
84     * JavaScript engine.
85     */
86    public abstract Object eval(String s) throws JSException;
87
88    /**
89     * Retrieves a named member of a JavaScript object. Equivalent to
90     * "this.name" in JavaScript.
91     *
92     * @param name The name of the JavaScript property to be accessed.
93     * @return The value of the propery.
94     * @throws JSException when an error is reported from the browser or
95     * JavaScript engine.
96     */
97    public abstract Object getMember(String name) throws JSException;
98
99    /**
100     * Sets a named member of a JavaScript object. Equivalent to
101     * "this.name = value" in JavaScript.
102     *
103     * @param name The name of the JavaScript property to be accessed.
104     * @param value The value of the propery.
105     * @throws JSException when an error is reported from the browser or
106     * JavaScript engine.
107     */
108    public abstract void setMember(String name, Object value) throws JSException;
109
110    /**
111     * Removes a named member of a JavaScript object. Equivalent
112     * to "delete this.name" in JavaScript.
113     *
114     * @param name The name of the JavaScript property to be removed.
115     * @throws JSException when an error is reported from the browser or
116     * JavaScript engine.
117     */
118    public abstract void removeMember(String name) throws JSException;
119
120    /**
121     * Retrieves an indexed member of a JavaScript object. Equivalent to
122     * "this[index]" in JavaScript.
123     *
124     * @param index The index of the array to be accessed.
125     * @return The value of the indexed member.
126     * @throws JSException when an error is reported from the browser or
127     * JavaScript engine.
128     */
129    public abstract Object getSlot(int index) throws JSException;
130
131    /**
132     * Sets an indexed member of a JavaScript object. Equivalent to
133     * "this[index] = value" in JavaScript.
134     *
135     * @param index The index of the array to be accessed.
136     * @param value The value to set
137     * @throws JSException when an error is reported from the browser or
138     * JavaScript engine.
139     */
140    public abstract void setSlot(int index, Object value) throws JSException;
141
142    /**
143     * Returns a JSObject for the window containing the given applet. This
144     * method only works when the Java code is running in a browser as an
145     * applet. The object returned may be used to access the HTML DOM directly.
146     *
147     * @param applet The applet.
148     * @return JSObject representing the window containing the given applet or
149     * {@code null} if we are not connected to a browser.
150     * @throws JSException when an error is reported from the browser or
151     * JavaScript engine or if applet is {@code null}
152     *
153     * @deprecated  The Applet API is deprecated. See the
154     * <a href="{@docRoot}/java/applet/package-summary.html">
155     * java.applet package documentation</a> for further information.
156     */
157
158    @Deprecated(since = "9")
159    @SuppressWarnings("exports")
160    public static JSObject getWindow(Applet applet) throws JSException {
161        return ProviderLoader.callGetWindow(applet);
162    }
163
164    private static class ProviderLoader {
165        private static final JSObjectProvider provider;
166
167        static {
168            provider = AccessController.doPrivileged(
169                new PrivilegedAction<>() {
170                    @Override
171                    public JSObjectProvider run() {
172                        Iterator<JSObjectProvider> providers =
173                            ServiceLoader.loadInstalled(JSObjectProvider.class).iterator();
174                        if (providers.hasNext()) {
175                            return providers.next();
176                        }
177                        return null;
178                    }
179                }
180            );
181        }
182
183        private static JSObject callGetWindow(Applet applet) {
184            if (provider != null) {
185                return provider.getWindow(applet);
186            }
187            return null;
188        }
189    }
190}
191