2003/05/12 05:10:30
[org.ibex.core.git] / src / org / mozilla / javascript / Delegator.java
1 /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
2  * The contents of this file are subject to the Mozilla Public License\r
3  * Version 1.1 (the "License"); you may not use this file except in\r
4  * compliance with the License. You may obtain a copy of the License at\r
5  * http://www.mozilla.org/MPL/\r
6  *\r
7  * Software distributed under the License is distributed on an "AS IS"\r
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\r
9  * License for the specific language governing rights and limitations\r
10  * under the License.\r
11  *\r
12  * The Original Code is Delegator.java, released Sep 27, 2000.\r
13  *\r
14  * The Initial Developer of the Original Code is Matthias Radestock.\r
15  * <matthias@sorted.org>. Portions created by Matthias Radestock are\r
16  * Copyright (C) 2000 Matthias Radestock. All Rights Reserved.\r
17  *\r
18  * Contributor(s):\r
19  *      Redfig Ltd (http://www.redfig.com)\r
20  *      LShift Ltd (http://www.lshift.net)\r
21  *\r
22  * Alternatively, the contents of this file may be used under the terms\r
23  * of the GNU Public License (the  "GPL License"), in which case the\r
24  * provisions of the GPL License are applicable instead of those\r
25  * above.  If you wish to allow use of your version of this file only\r
26  * under the terms of the GPL License and not to allow others to use\r
27  * your version of this file under the MPL, indicate your decision by\r
28  * deleting  the provisions above and replace  them with the notice and\r
29  * other provisions required by the GPL License.  If you do not delete\r
30  * the provisions above, a recipient may use your version of this file\r
31  * under either the MPL or the GPL License.\r
32  */\r
33 \r
34 // API class\r
35 \r
36 package org.mozilla.javascript;\r
37 \r
38 /**\r
39  * This is a helper class for implementing wrappers around Scriptable\r
40  * objects. It implements the Function interface and delegates all\r
41  * invocations to a delegee Scriptable object. The normal use of this\r
42  * class involves creating a sub-class and overriding one or more of\r
43  * the methods.\r
44  *\r
45  * A useful application is the implementation of interceptors,\r
46  * pre/post conditions, debugging.\r
47  *\r
48  * @see Function\r
49  * @see Scriptable\r
50  * @author Matthias Radestock\r
51  */\r
52 \r
53 public class Delegator implements Function {\r
54 \r
55     protected Scriptable obj = null;\r
56 \r
57     /**\r
58      * Create a Delegator prototype.\r
59      *\r
60      * This constructor should only be used for creating prototype\r
61      * objects of Delegator.\r
62      *\r
63      * @see org.mozilla.javascript.Delegator#construct\r
64      */\r
65     public Delegator() {\r
66     }\r
67 \r
68     /**\r
69      * Create a new Delegator that forwards requests to a delegee\r
70      * Scriptable object.\r
71      *\r
72      * @param obj the delegee\r
73      * @see org.mozilla.javascript.Scriptable\r
74      */\r
75     public Delegator(Scriptable obj) {\r
76         this.obj = obj;\r
77     }\r
78 \r
79     /**\r
80      * Retrieve the delegee.\r
81      *\r
82      * @return the delegee\r
83      */\r
84     public Scriptable getDelegee() {\r
85         return obj;\r
86     }\r
87     /**\r
88      * Set the delegee.\r
89      *\r
90      * @param obj the delegee\r
91      * @see org.mozilla.javascript.Scriptable\r
92      */\r
93     public void setDelegee(Scriptable obj) {\r
94         this.obj = obj;\r
95     }\r
96     /**\r
97      * @see org.mozilla.javascript.Scriptable#getClassName\r
98      */\r
99     public String getClassName() {\r
100         return obj.getClassName();\r
101     }\r
102     /**\r
103      * @see org.mozilla.javascript.Scriptable#get\r
104      */\r
105     public Object get(String name, Scriptable start) {\r
106         return obj.get(name,start);\r
107     }\r
108     /**\r
109      * @see org.mozilla.javascript.Scriptable#get\r
110      */\r
111     public Object get(int index, Scriptable start) {\r
112         return obj.get(index,start);\r
113         }\r
114     /**\r
115      * @see org.mozilla.javascript.Scriptable#has\r
116      */\r
117     public boolean has(String name, Scriptable start) {\r
118         return obj.has(name,start);\r
119         }\r
120     /**\r
121      * @see org.mozilla.javascript.Scriptable#has\r
122      */\r
123     public boolean has(int index, Scriptable start) {\r
124         return obj.has(index,start);\r
125         }\r
126     /**\r
127      * @see org.mozilla.javascript.Scriptable#put\r
128      */\r
129     public void put(String name, Scriptable start, Object value) {\r
130         obj.put(name,start,value);\r
131     }\r
132     /**\r
133      * @see org.mozilla.javascript.Scriptable#put\r
134      */\r
135     public void put(int index, Scriptable start, Object value) {\r
136         obj.put(index,start,value);\r
137     }\r
138     /**\r
139      * @see org.mozilla.javascript.Scriptable#delete\r
140      */\r
141     public void delete(String name) {\r
142         obj.delete(name);\r
143     }\r
144     /**\r
145      * @see org.mozilla.javascript.Scriptable#delete\r
146      */\r
147     public void delete(int index) {\r
148         obj.delete(index);\r
149     }\r
150     /**\r
151      * @see org.mozilla.javascript.Scriptable#getPrototype\r
152      */\r
153     public Scriptable getPrototype() {\r
154         return obj.getPrototype();\r
155     }\r
156     /**\r
157      * @see org.mozilla.javascript.Scriptable#setPrototype\r
158      */\r
159     public void setPrototype(Scriptable prototype) {\r
160         obj.setPrototype(prototype);\r
161     }\r
162     /**\r
163      * @see org.mozilla.javascript.Scriptable#getParentScope\r
164      */\r
165     public Scriptable getParentScope() {\r
166         return obj.getParentScope();\r
167     }\r
168     /**\r
169      * @see org.mozilla.javascript.Scriptable#setParentScope\r
170      */\r
171     public void setParentScope(Scriptable parent) {\r
172         obj.setParentScope(parent);\r
173     }\r
174     /**\r
175      * @see org.mozilla.javascript.Scriptable#getIds\r
176      */\r
177     public Object[] getIds() {\r
178         return obj.getIds();\r
179     }\r
180     /**\r
181      * Note that this method does not get forwarded to the delegee if\r
182      * the <code>hint</code> parameter is null,\r
183      * <code>ScriptRuntime.ScriptableClass</code> or\r
184      * <code>ScriptRuntime.FunctionClass</code>. Instead the object\r
185      * itself is returned.\r
186      *\r
187      * @param hint the type hint\r
188      * @return the default value\r
189      *\r
190      * @see org.mozilla.javascript.Scriptable#getDefaultValue\r
191      */\r
192     public Object getDefaultValue(Class hint) {\r
193         return (hint == null ||\r
194                 hint == ScriptRuntime.ScriptableClass ||\r
195                 hint == ScriptRuntime.FunctionClass) ?\r
196             this : obj.getDefaultValue(hint);\r
197     }\r
198     /**\r
199      * @see org.mozilla.javascript.Scriptable#hasInstance\r
200      */\r
201     public boolean hasInstance(Scriptable instance) {\r
202         return obj.hasInstance(instance);\r
203     }\r
204     /**\r
205      * @see org.mozilla.javascript.Function#call\r
206      */\r
207     public Object call(Context cx, Scriptable scope, Scriptable thisObj,\r
208                        Object[] args)\r
209         throws JavaScriptException {\r
210         return ((Function)obj).call(cx,scope,thisObj,args);\r
211     }\r
212 \r
213     /**\r
214      * Note that if the <code>delegee</code> is <code>null</code>,\r
215      * this method creates a new instance of the Delegator itself\r
216      * rathert than forwarding the call to the\r
217      * <code>delegee</code>. This permits the use of Delegator\r
218      * prototypes.\r
219      *\r
220      * @param cx the current Context for this thread\r
221      * @param scope an enclosing scope of the caller except\r
222      *              when the function is called from a closure.\r
223      * @param args the array of arguments\r
224      * @return the allocated object\r
225      * @exception JavaScriptException if an uncaught exception\r
226      *            occurred while executing the constructor\r
227      *\r
228      * @see org.mozilla.javascript.Function#construct\r
229      */\r
230     public Scriptable construct(Context cx, Scriptable scope, Object[] args)\r
231         throws JavaScriptException {\r
232         if (obj == null) {\r
233             //this little trick allows us to declare prototype objects for\r
234             //Delegators\r
235             try {\r
236                 Delegator n = (Delegator)this.getClass().newInstance();\r
237                 n.setDelegee((Scriptable)args[0]);\r
238                 return n;\r
239             }\r
240             catch (Exception e) {\r
241                 e.printStackTrace();\r
242                 throw new Error("exception in org.mozilla.javascript.Delegator.construct()");\r
243                 //System.exit(0);\r
244             }\r
245         }\r
246         else {\r
247             return ((Function)obj).construct(cx,scope,args);\r
248         }\r
249     }\r
250 }\r