001: /*
002: * $Id: NativeNamespace.java,v 1.5 2002/09/16 08:05:04 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.script.compiler;
011:
012: import anvil.core.Any;
013: import anvil.core.runtime.AnyFunction;
014: import anvil.core.runtime.AnyScope;
015: import anvil.core.runtime.AnyType;
016: import anvil.core.Modules;
017: import anvil.Log;
018: import anvil.doc.Doc;
019: import anvil.script.Context;
020: import anvil.script.CompilableFunction;
021: import anvil.script.ConstantVariableType;
022: import anvil.script.Grammar;
023: import anvil.script.Type;
024: import anvil.script.NativeJava;
025: import anvil.script.ClassType;
026: import anvil.script.InterfaceType;
027: import anvil.script.Function;
028: import anvil.script.Scope;
029: import anvil.java.util.BindingEnumeration;
030: import java.io.IOException;
031: import java.lang.reflect.Field;
032: import java.lang.reflect.Method;
033: import java.lang.reflect.Modifier;
034: import java.util.Enumeration;
035: import java.util.Hashtable;
036:
037: /**
038: * class NativeNamespace
039: *
040: * @author: Jani Lehtimäki
041: */
042: public class NativeNamespace implements Scope, NativeJava {
043:
044: private Any _wrapper;
045: private Class _class;
046: private String _classname;
047: private String _name;
048: private String _qname;
049: private Doc _document;
050: private Scope _parent;
051: private Hashtable _types = new Hashtable();
052:
053: private static Class[] loadClasses(String[] classnames) {
054: int n = classnames.length;
055: Class[] classes = new Class[n];
056: for (int i = 0; i < n; i++) {
057: try {
058: classes[i] = Class.forName(classnames[i]);
059: } catch (Throwable t) {
060: anvil.Log.log().error(t);
061: }
062: }
063: return classes;
064: }
065:
066: public NativeNamespace(String moduleName, Class module,
067: String[] classnames) {
068: this (moduleName, module, loadClasses(classnames), "");
069: }
070:
071: public NativeNamespace(String moduleName, Class module,
072: String[] classnames, String document) {
073: this (moduleName, module, loadClasses(classnames), document);
074: }
075:
076: public NativeNamespace(String moduleName, Class module,
077: Class[] classes) {
078: this (moduleName, module, classes, "");
079: }
080:
081: public NativeNamespace(String moduleName, Class module,
082: Class[] classes, String document) {
083: try {
084: //_wrapper = new AnyScope(this);
085: _class = module;
086: _classname = module.getName();
087: _name = moduleName;
088: _document = anvil.doc.DocParser.parse(document);
089:
090: if (classes != null) {
091: int n = classes.length;
092: for (int i = 0; i < n; i++) {
093: Class cls = classes[i];
094: if (Any.class.isAssignableFrom(cls)) {
095: NativeClass classtype = (NativeClass) Compiled
096: .getstatic(classes[i], "__class__");
097: if (classtype != null) {
098: _types.put(classtype.getName(), classtype);
099: classtype.setParent(this );
100: }
101: } else {
102: NativeNamespace scope = (NativeNamespace) Compiled
103: .getstatic(classes[i], "__module__");
104: if (scope != null) {
105: _types.put(scope.getName(), scope);
106: scope.setParent(this );
107: }
108:
109: }
110: }
111: }
112:
113: /* methods */{
114: Method[] methods = module.getDeclaredMethods();
115: Object[] parameters;
116: CompilableFunction function;
117: int n = methods.length;
118: for (int i = 0; i < n; i++) {
119: Method method = methods[i];
120: String name = method.getName();
121: int mod = method.getModifiers();
122: if (Modifier.isPublic(mod)
123: && Modifier.isStatic(mod)) {
124: if (method.getReturnType().equals(Any.class)) {
125: Doc doc = _document.findFirst(
126: Doc.T_FUNCTION, name);
127: parameters = (Object[]) Compiled.getstatic(
128: module, "p_" + name);
129: function = new NativeFunction(this , method,
130: name, parameters, doc);
131: _types.put(function.getName(), function);
132: }
133: }
134: }
135: }
136:
137: /* fields */{
138: Field[] fields = module.getDeclaredFields();
139: int n = fields.length;
140: for (int i = 0; i < n; i++) {
141: Field field = fields[i];
142: String name = field.getName();
143: int mod = field.getModifiers();
144: if (name.startsWith("p_")) {
145: continue;
146: }
147: if (name.startsWith("_")) {
148: continue;
149: }
150: if (Modifier.isPublic(mod)
151: && Modifier.isStatic(mod)
152: && Modifier.isFinal(mod)) {
153: try {
154: Object obj = field.get(null);
155: if (obj instanceof Any) {
156: Doc doc = _document.findFirst(
157: Doc.T_CONST, name);
158: Any value = (Any) obj;
159: _types
160: .put(
161: name,
162: new NativeConstantVariable(
163: this , name,
164: field, doc));
165: }
166: } catch (Exception e) {
167: anvil.Log.log().error(
168: "Couldn't get field '" + field
169: + "' from "
170: + module.getName());
171: }
172: }
173: }
174: }
175:
176: } catch (Throwable t) {
177: anvil.Log.log().error(t);
178: }
179: }
180:
181: public void setParent(Scope parent) {
182: _parent = parent;
183: }
184:
185: public String toString() {
186: return "namespace " + getQualifiedName();
187: }
188:
189: public String getName() {
190: return _name;
191: }
192:
193: public final String getQualifiedName() {
194: if (_qname == null) {
195: _qname = Grammar.buildQualifiedName(this );
196: }
197: return _qname;
198: }
199:
200: public int getType() {
201: return NAMESPACE;
202: }
203:
204: public Scope getParent() {
205: if (_parent == null) {
206: _parent = Modules.getInstance();
207: }
208: return _parent;
209: }
210:
211: public Doc getDocument() {
212: return _document;
213: }
214:
215: public Enumeration getDeclarations() {
216: return _types.elements();
217: }
218:
219: public Type lookupDeclaration(String name) {
220: return (Type) _types.get(name);
221: }
222:
223: public final Any execute(Context context, String name,
224: Any[] parameters) {
225: Type type = (Type) _types.get(name);
226: if (type != null) {
227: if (type.getType() == FUNCTION) {
228: return ((Function) type).execute(context, parameters);
229: }
230: }
231: throw context.NoSuchFunction(_name + '.' + name);
232: }
233:
234: public Any getFunction(Context context, String name) {
235: Type type = (Type) _types.get(name);
236: if (type != null) {
237: if (type.getType() == FUNCTION) {
238: return new AnyFunction((Function) type);
239: }
240: }
241: throw context.NoSuchFunction(_name + '.' + name);
242: }
243:
244: public Any getType(Context context, String name) {
245: Type type = (Type) _types.get(name);
246: if (type != null) {
247: return new AnyType(type);
248: }
249: throw context.NoSuchEntity(_name + '.' + name);
250: }
251:
252: public Type getDeclaration(Context context, String name) {
253: Type type = (Type) _types.get(name);
254: if (type != null) {
255: return type;
256: }
257: throw context.NoSuchEntity(_name + '.' + name);
258: }
259:
260: public Any newInstance(Context context, String name,
261: Any[] parameters) {
262: Type type = (Type) _types.get(name);
263: if (type != null) {
264: if (type.getType() == CLASS) {
265: ClassType clazz = (ClassType) type;
266: return clazz.getConstructor().execute(context,
267: parameters);
268: }
269: }
270: throw context.NoSuchClass(_name + '.' + name);
271: }
272:
273: public Any getWrapper() {
274: if (_wrapper == null) {
275: _wrapper = new AnyType(this );
276: }
277: return _wrapper;
278: }
279:
280: public int getTypeRef(anvil.codec.ConstantPool pool) {
281: return pool.addClass(_class.getName().replace('.', '/'));
282: }
283:
284: }
|