2003/05/12 05:10:30
[org.ibex.core.git] / src / org / mozilla / javascript / ImporterTopLevel.java
1 /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
2  *\r
3  * The contents of this file are subject to the Netscape Public\r
4  * License Version 1.1 (the "License"); you may not use this file\r
5  * except in compliance with the License. You may obtain a copy of\r
6  * the License at http://www.mozilla.org/NPL/\r
7  *\r
8  * Software distributed under the License is distributed on an "AS\r
9  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
10  * implied. See the License for the specific language governing\r
11  * rights and limitations under the License.\r
12  *\r
13  * The Original Code is Rhino code, released\r
14  * May 6, 1999.\r
15  *\r
16  * The Initial Developer of the Original Code is Netscape\r
17  * Communications Corporation.  Portions created by Netscape are\r
18  * Copyright (C) 1999 Netscape Communications Corporation. All\r
19  * Rights Reserved.\r
20  *\r
21  * Contributor(s): \r
22  * Norris Boyd\r
23  * Matthias Radestock\r
24  *\r
25  * Alternatively, the contents of this file may be used under the\r
26  * terms of the GNU Public License (the "GPL"), in which case the\r
27  * provisions of the GPL are applicable instead of those above.\r
28  * If you wish to allow use of your version of this file only\r
29  * under the terms of the GPL and not to allow others to use your\r
30  * version of this file under the NPL, indicate your decision by\r
31  * deleting the provisions above and replace them with the notice\r
32  * and other provisions required by the GPL.  If you do not delete\r
33  * the provisions above, a recipient may use your version of this\r
34  * file under either the NPL or the GPL.\r
35  */\r
36 \r
37 // API class\r
38 \r
39 package org.mozilla.javascript;\r
40 \r
41 import java.util.Vector;\r
42 \r
43 /**\r
44  * Class ImporterTopLevel\r
45  * \r
46  * This class defines a ScriptableObject that can be instantiated \r
47  * as a top-level ("global") object to provide functionality similar\r
48  * to Java's "import" statement.\r
49  * <p>\r
50  * This class can be used to create a top-level scope using the following code: \r
51  * <pre>\r
52  *  Scriptable scope = new ImporterTopLevel(cx);\r
53  * </pre>\r
54  * Then JavaScript code will have access to the following methods:\r
55  * <ul>\r
56  * <li>importClass - will "import" a class by making its unqualified name \r
57  *                   available as a property of the top-level scope\r
58  * <li>importPackage - will "import" all the classes of the package by \r
59  *                     searching for unqualified names as classes qualified\r
60  *                     by the given package.\r
61  * </ul>\r
62  * The following code from the shell illustrates this use:\r
63  * <pre>\r
64  * js> importClass(java.io.File)\r
65  * js> f = new File('help.txt')\r
66  * help.txt\r
67  * js> importPackage(java.util)\r
68  * js> v = new Vector()\r
69  * []\r
70  * \r
71  * @author Norris Boyd\r
72  */\r
73 public class ImporterTopLevel extends ScriptableObject {\r
74     \r
75     /**\r
76      * @deprecated\r
77      */\r
78     public ImporterTopLevel() {\r
79         init();\r
80     }\r
81 \r
82     public ImporterTopLevel(Context cx) {\r
83         cx.initStandardObjects(this);\r
84         init();\r
85     }\r
86     \r
87     private void init() {\r
88         String[] names = { "importClass", "importPackage" };\r
89 \r
90         try {\r
91             this.defineFunctionProperties(names, ImporterTopLevel.class,\r
92                                           ScriptableObject.DONTENUM);\r
93         } catch (PropertyException e) {\r
94             throw new Error();  // should never happen\r
95         }\r
96     }\r
97 \r
98     public String getClassName() { \r
99         return "global";\r
100     }\r
101     \r
102     public Object get(String name, Scriptable start) {\r
103         Object result = super.get(name, start);\r
104         if (result != NOT_FOUND) \r
105             return result;\r
106         if (name.equals("_packages_")) \r
107             return result;\r
108         Object plist = ScriptableObject.getProperty(start,"_packages_");\r
109         if (plist == NOT_FOUND) \r
110             return result;\r
111         Context cx = Context.enter();\r
112         Object[] elements = cx.getElements((Scriptable)plist);\r
113         Context.exit();\r
114         for (int i=0; i < elements.length; i++) {\r
115             NativeJavaPackage p = (NativeJavaPackage) elements[i];\r
116             Object v = p.getPkgProperty(name, start, false);\r
117             if (v != null && !(v instanceof NativeJavaPackage)) {\r
118                 if (result == NOT_FOUND) {\r
119                     result = v;\r
120                 } else {\r
121                     throw Context.reportRuntimeError2(\r
122                         "msg.ambig.import", result.toString(), v.toString());\r
123                 }\r
124             }\r
125         }\r
126         return result;\r
127     }\r
128     \r
129     public static void importClass(Context cx, Scriptable thisObj,\r
130                                    Object[] args, Function funObj) {\r
131         for (int i=0; i<args.length; i++) {\r
132             Object cl = args[i];\r
133             if (!(cl instanceof NativeJavaClass)) {\r
134                 throw Context.reportRuntimeError1(\r
135                     "msg.not.class", Context.toString(cl));\r
136             }\r
137             String s = ((NativeJavaClass) cl).getClassObject().getName();\r
138             String n = s.substring(s.lastIndexOf('.')+1);\r
139             Object val = thisObj.get(n, thisObj);\r
140             if (val != NOT_FOUND && val != cl) {\r
141                 throw Context.reportRuntimeError1("msg.prop.defined", n);\r
142             }\r
143             //thisObj.defineProperty(n, cl, DONTENUM);\r
144             thisObj.put(n,thisObj,cl);\r
145         }\r
146     }\r
147     \r
148     public static void importPackage(Context cx, Scriptable thisObj,\r
149                                    Object[] args, Function funObj) {\r
150         Scriptable importedPackages;\r
151         Object plist = thisObj.get("_packages_", thisObj);\r
152         if (plist == NOT_FOUND) {\r
153             importedPackages = cx.newArray(thisObj,0);\r
154             thisObj.put("_packages_", thisObj, importedPackages);\r
155         }\r
156         else {\r
157             importedPackages = (Scriptable)plist;\r
158         }\r
159         for (int i=0; i<args.length; i++) {\r
160             Object pkg = args[i];\r
161             if (!(pkg instanceof NativeJavaPackage)) {\r
162                 throw Context.reportRuntimeError1(\r
163                     "msg.not.pkg", Context.toString(pkg));\r
164             }\r
165             Object[] elements = cx.getElements(importedPackages);\r
166             for (int j=0; j < elements.length; j++) {\r
167                 if (pkg == elements[j]) {\r
168                     pkg = null;\r
169                     break;\r
170                 }\r
171             }\r
172             if (pkg != null)\r
173                 importedPackages.put(elements.length,importedPackages,pkg);\r
174         }\r
175     }\r
176 }\r