001: /*
002: * $Id: Modules.java,v 1.35 2002/09/16 08:05:02 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.core;
011:
012: import java.util.Iterator;
013: import java.util.Enumeration;
014: import java.util.HashMap;
015: import anvil.Log;
016: import anvil.doc.Doc;
017: import anvil.codec.ConstantPool;
018: import anvil.server.Zone;
019: import anvil.script.compiler.NativeNamespace;
020: import anvil.script.Grammar;
021: import anvil.script.Name;
022: import anvil.script.Scope;
023: import anvil.script.IncrementalScope;
024: import anvil.script.Type;
025: import anvil.script.NativeJava;
026: import anvil.script.Synthetic;
027: import anvil.script.Module;
028: import anvil.java.util.Hashlist;
029: import anvil.java.util.BindingEnumeration;
030: import anvil.server.Address;
031: import anvil.script.Dependency;
032:
033: /**
034: * class Modules
035: *
036: * @author: Jani Lehtimäki
037: */
038: public class Modules implements NativeJava, IncrementalScope, Module {
039:
040: public static final String NAME = "$$native";
041: public static final Any ANY_NAME = Any.create(NAME);
042:
043: protected static class SyntheticNamespace implements
044: IncrementalScope, NativeJava, Synthetic {
045: private Scope _parent;
046: private String _name;
047: private String _qname;
048: private Hashlist _types = new Hashlist();
049:
050: protected SyntheticNamespace(Scope parent, String name) {
051: _parent = parent;
052: _name = name;
053: }
054:
055: public String toString() {
056: return "SyntheticNamespace(" + _name + ")";
057: }
058:
059: public void addDeclaration(Type type) {
060: _types.put(type.getName(), type);
061: }
062:
063: public String getName() {
064: return _name;
065: }
066:
067: public final String getQualifiedName() {
068: if (_qname == null) {
069: _qname = Grammar.buildQualifiedName(this );
070: }
071: return _qname;
072: }
073:
074: public int getType() {
075: return NAMESPACE;
076: }
077:
078: public Scope getParent() {
079: return _parent;
080: }
081:
082: public Doc getDocument() {
083: return null;
084: }
085:
086: public int getTypeRef(ConstantPool pool) {
087: return 0;
088: }
089:
090: public Enumeration getDeclarations() {
091: return _types.elements();
092: }
093:
094: public Type lookupDeclaration(String name) {
095: return (Type) _types.get(name);
096: }
097:
098: }
099:
100: private static Modules _instance;
101:
102: public static final Modules getInstance() {
103: if (_instance == null) {
104: synchronized (Modules.class) {
105: _instance = new Modules();
106: }
107: }
108: return _instance;
109: }
110:
111: private Hashlist _types = new Hashlist();
112:
113: public Modules() {
114: addDeclaration(Anvil.__module__);
115: }
116:
117: public String toString() {
118: return NAME;
119: }
120:
121: public void addDeclaration(Type type) {
122: _types.put(type.getName(), type);
123: }
124:
125: public synchronized void register(String dottedname,
126: NativeNamespace lib) {
127: if (!Grammar.isValidIdentifier(lib.getName())) {
128: throw new RuntimeException("Name of '" + dottedname
129: + "' is invalid");
130: }
131: Name name = Grammar.parseDottedName(dottedname);
132: IncrementalScope scope = this ;
133: int i = 0;
134: int n = name.size();
135: while (i < n) {
136: String s = name.get(i++);
137: Type type = scope.lookupDeclaration(s);
138: if (type == null) {
139: if (i < n) {
140: SyntheticNamespace ns = new SyntheticNamespace(
141: scope, s);
142: scope.addDeclaration(ns);
143: scope = ns;
144: } else {
145: scope.addDeclaration(lib);
146: lib.setParent(scope);
147: return;
148: }
149: } else {
150: if (type instanceof IncrementalScope) {
151: scope = (IncrementalScope) type;
152: } else {
153: break;
154: }
155: }
156: }
157: throw new RuntimeException(
158: "Library '"
159: + dottedname
160: + "' cannot be embedded into module structure; non-scoped or read-only type encountered");
161: }
162:
163: public synchronized void register(String dottedname,
164: String classname) {
165: try {
166: Class cls = Class.forName(classname);
167: NativeNamespace ns = (NativeNamespace) anvil.script.compiler.Compiled
168: .getstatic(cls, "__module__");
169: if (ns == null) {
170: throw new RuntimeException(
171: "Static field __module__ is null - couldn't load module '"
172: + classname + "' as '" + dottedname
173: + "'");
174: }
175: register(dottedname, ns);
176:
177: } catch (Throwable t) {
178: anvil.Log.log().error(t);
179: throw new RuntimeException("Couldn't load module '"
180: + classname + "' as '" + dottedname + "', reason: "
181: + t);
182: }
183: }
184:
185: public String getName() {
186: return NAME;
187: }
188:
189: public String getQualifiedName() {
190: return NAME;
191: }
192:
193: public int getType() {
194: return MODULE;
195: }
196:
197: public Scope getParent() {
198: return null;
199: }
200:
201: public Doc getDocument() {
202: return null;
203: }
204:
205: public int getTypeRef(ConstantPool pool) {
206: return 0;
207: }
208:
209: public Enumeration getDeclarations() {
210: return _types.elements();
211: }
212:
213: public Type lookupDeclaration(String name) {
214: return (Type) _types.get(name);
215: }
216:
217: public Address getAddress() {
218: return null;
219: }
220:
221: public String getPathinfo() {
222: return NAME;
223: }
224:
225: public String getDescriptor() {
226: return null;
227: }
228:
229: public Iterator getDependencies() {
230: return null;
231: }
232:
233: public Dependency getDependency(Address address) {
234: return null;
235: }
236:
237: }
|