View Javadoc
1   /*
2    * Copyright (c) 2002-2024 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package netscape.javascript;
16  
17  import java.applet.Applet;
18  import java.util.Arrays;
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.htmlunit.Page;
23  import org.htmlunit.ScriptResult;
24  import org.htmlunit.corejs.javascript.ScriptableObject;
25  import org.htmlunit.html.HtmlPage;
26  import org.htmlunit.javascript.JavaScriptEngine;
27  import org.htmlunit.javascript.host.Element;
28  import org.htmlunit.javascript.host.Window;
29  
30  /**
31   * Stub for the JSException. This is part of the Applet
32   * LiveConnect simulation.
33   *
34   * @author Ronald Brill
35   */
36  public class JSObject {
37  
38      private static final Log LOG = LogFactory.getLog(JSObject.class);
39  
40      private static Window Window_;
41      private final ScriptableObject scriptableObject_;
42  
43      /**
44       * Constructor.
45       *
46       * @param scriptableObject the wrapped scriptableObject
47       */
48      public JSObject(final ScriptableObject scriptableObject) {
49          scriptableObject_ = scriptableObject;
50      }
51  
52      /**
53       * Calls a JavaScript method.
54       * Equivalent to "this.methodName(args[0], args[1], ...)" in JavaScript.
55       *
56       * @param methodName the name of the JavaScript method to be invoked
57       * @param args an array of Java object to be passed as arguments to the method
58       * @return result result of the method
59       * @throws JSException in case or error
60       */
61      public Object call(final String methodName, final Object[] args) throws JSException {
62          if (LOG.isInfoEnabled()) {
63              LOG.info("JSObject call '" + methodName + "(" + Arrays.toString(args) + ")'");
64          }
65  
66          final Object jsResult = ScriptableObject.callMethod(scriptableObject_, methodName, args);
67          if (jsResult instanceof ScriptableObject) {
68              return new JSObject((ScriptableObject) jsResult);
69          }
70          if (jsResult instanceof CharSequence) {
71              return jsResult.toString();
72          }
73          return jsResult;
74      }
75  
76      /**
77       * Evaluates a JavaScript expression.
78       * The expression is a string of JavaScript source code which will be evaluated in the context given by "this".
79       *
80       * @param expression the JavaScript expression
81       * @return result Object
82       * @throws JSException in case or error
83       */
84      public Object eval(final String expression) throws JSException {
85          if (LOG.isInfoEnabled()) {
86              LOG.info("JSObject eval '" + expression + "'");
87          }
88  
89          final Page page = Window_.getWebWindow().getEnclosedPage();
90          if (page instanceof HtmlPage) {
91              final HtmlPage htmlPage = (HtmlPage) page;
92              final ScriptResult result = htmlPage.executeJavaScript(expression);
93              final Object jsResult = result.getJavaScriptResult();
94              if (jsResult instanceof ScriptableObject) {
95                  return new JSObject((ScriptableObject) jsResult);
96              }
97              if (jsResult instanceof CharSequence) {
98                  return jsResult.toString();
99              }
100             return jsResult;
101         }
102         return null;
103     }
104 
105     /**
106      * Retrieves a named member of a JavaScript object.
107      * Equivalent to "this.name" in JavaScript.
108      *
109      * @param name the name of the JavaScript property to be accessed
110      * @return result Object
111      * @throws JSException in case or error
112      */
113     public Object getMember(final String name) throws JSException {
114         if (LOG.isInfoEnabled()) {
115             LOG.info("JSObject getMember '" + name + "'");
116         }
117 
118         if (scriptableObject_ instanceof Element) {
119             return  ((Element) scriptableObject_).getAttribute(name, null);
120         }
121         return scriptableObject_.get(name, scriptableObject_);
122     }
123 
124     /**
125      * Sets a named member of a JavaScript object.
126      * Equivalent to "this.name = value" in JavaScript.
127      *
128      * @param name the name of the JavaScript property to be accessed
129      * @param value the value of the property
130      * @throws JSException in case or error
131      */
132     public void setMember(final String name, final Object value) throws JSException {
133         String stringValue = "";
134         if (value != null) {
135             stringValue = JavaScriptEngine.toString(value);
136         }
137 
138         if (LOG.isInfoEnabled()) {
139             LOG.info("JSObject setMember '" + name + "' to '" + stringValue + "'");
140         }
141 
142         if (scriptableObject_ instanceof Element) {
143             ((Element) scriptableObject_).setAttribute(name, stringValue);
144             return;
145         }
146         scriptableObject_.put(name, scriptableObject_, value);
147     }
148 
149     /**
150      * Removes a named member of a JavaScript object.
151      * Equivalent to "delete this.name" in JavaScript.
152      *
153      * @param name the name of the JavaScript property to be accessed
154      * @throws JSException in case or error
155      */
156     public void removeMember(final String name) throws JSException {
157         LOG.error("Not yet implemented (netscape.javascript.JSObject.removeMember(String)).");
158         throw new RuntimeException("Not yet implemented (netscape.javascript.JSObject.removeMember(String)).");
159     }
160 
161     /**
162      * Retrieves an indexed member of a JavaScript object.
163      * Equivalent to "this[index]" in JavaScript.
164      *
165      * @param index the index of the array to be accessed
166      * @return result the value of the indexed member
167      * @throws JSException in case or error
168      */
169     public Object getSlot(final int index) throws JSException {
170         LOG.error("Not yet implemented (netscape.javascript.JSObject.getSlot(int)).");
171         throw new RuntimeException("Not yet implemented (netscape.javascript.JSObject.getSlot(int)).");
172     }
173 
174     /**
175      * Sets an indexed member of a JavaScript object.
176      * Equivalent to "this[index] = value" in JavaScript.
177      *
178      * @param index the index of the array to be accessed
179      * @param value the value of the property
180      * @throws JSException in case or error
181      */
182     public void setSlot(final int index, final Object value) throws JSException {
183         LOG.error("Not yet implemented (netscape.javascript.JSObject.setSlot(int, Object)).");
184         throw new RuntimeException("Not yet implemented (netscape.javascript.JSObject.setSlot(int, Object)).");
185     }
186 
187     /**
188      * Returns a JSObject for the window containing the given applet.
189      *
190      * @param paramApplet the paramApplet
191      * @return result Object
192      * @throws JSException in case or error
193      */
194     public static JSObject getWindow(final Applet paramApplet) throws JSException {
195         return new JSObject(Window_);
196     }
197 
198     /**
199      * Sets the window this class works for.
200      * Every applet works inside his onw class loaders, and this class
201      * will be loaded separatly into every one.
202      *
203      * @param window the window
204      */
205     public static void setWindow(final Window window) {
206         Window_ = window;
207     }
208 }