KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > kawa > lang > AutoloadProcedure


1 package kawa.lang;
2 import gnu.mapping.*;
3 import gnu.expr.*;
4 import java.io.*;
5
6 /**
7  * Implement autoloading of Procedures.
8  * A named class is loaded, and apply requests are forwarded to it.
9  * @author Per Bothner
10  */

11
12 public class AutoloadProcedure extends Procedure implements Externalizable
13 {
14   /** The name of the class that defines the procedure.
15    * It must be the name of a class in the CLASSPATH (for example:
16    * "kawa.standard.list"), and the class must extend Procedure,
17    * and have a default constructor.
18    * If the Procedure is a ModuleMody, apply0() is applied,
19    * and that is expected to define the Procedure in the global environment. */

20   String JavaDoc className;
21
22   Language language;
23
24   /** The loaded procedure, or null if it has not yet been loaded. */
25   Procedure loaded;
26
27   public AutoloadProcedure ()
28   {
29   }
30
31   public AutoloadProcedure (String JavaDoc name, String JavaDoc className)
32   {
33     super(name);
34     this.className = className;
35   }
36
37   public AutoloadProcedure (String JavaDoc name, String JavaDoc className, Language language)
38   {
39     super(name);
40     this.className = className;
41     this.language = language;
42   }
43
44   public void print(java.io.PrintWriter JavaDoc ps)
45   {
46     ps.print ("#<procedure ");
47     String JavaDoc name = getName();
48     if (name != null)
49       {
50     ps.print (name);
51     // ps.print (' ');
52
}
53     /*
54     if (loaded != null)
55       ps.print ("autoloaded");
56     else
57       {
58     ps.print ("autoload ");
59     ps.print (className);
60       }
61     */

62     ps.print ('>');
63   }
64
65   private void throw_error (String JavaDoc prefix)
66   {
67     loaded = null;
68     String JavaDoc name = getName();
69     throw new RuntimeException JavaDoc (prefix + className
70                 + " while autoloading "
71                 + (name == null ? "" : name.toString ()));
72   }
73
74   /** Load the class named in className. */
75   void load ()
76   {
77     Object JavaDoc name = this.getSymbol();
78     try
79       {
80     loaded = (Procedure) Class.forName (className).newInstance ();
81     if (loaded == this)
82       throw_error("circularity detected");
83     if (name != null)
84       {
85         try
86           {
87         Object JavaDoc property = (language.hasSeparateFunctionNamespace()
88                    ? EnvironmentKey.FUNCTION
89                    : null);
90         // Should use something like isFunctionBound FIXME
91
Environment env = language.getLangEnvironment();
92         Symbol sym = (name instanceof Symbol ? (Symbol) name
93                   : env.getSymbol(name.toString()));
94         env.put(sym, property, loaded);
95           }
96         catch (UnboundLocationException ex)
97           {
98           }
99         if (loaded.getSymbol() == null)
100           loaded.setSymbol(name);
101       }
102       }
103     catch (ClassNotFoundException JavaDoc ex)
104       { throw_error ("failed to find class "); }
105     catch (InstantiationException JavaDoc ex)
106       { throw_error ("failed to instantiate class "); }
107     catch (IllegalAccessException JavaDoc ex)
108       { throw_error ("illegal access in class "); }
109   }
110
111   public Procedure getLoaded ()
112   {
113     if (loaded == null)
114       load();
115     return loaded;
116   }
117
118   public int numArgs ()
119   {
120     return getLoaded().numArgs();
121   }
122
123   public Object JavaDoc apply0 () throws Throwable JavaDoc
124   {
125     return getLoaded().apply0 ();
126   }
127
128   public Object JavaDoc apply1 (Object JavaDoc arg1) throws Throwable JavaDoc
129   {
130     return getLoaded().apply1 (arg1);
131   }
132
133    public Object JavaDoc apply2 (Object JavaDoc arg1,Object JavaDoc arg2) throws Throwable JavaDoc
134   {
135     return getLoaded().apply2 (arg1, arg2);
136   }
137
138   public Object JavaDoc apply3 (Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3) throws Throwable JavaDoc
139   {
140     return getLoaded().apply3 (arg1, arg2, arg3);
141   }
142
143   public Object JavaDoc apply4 (Object JavaDoc arg1, Object JavaDoc arg2,
144             Object JavaDoc arg3, Object JavaDoc arg4) throws Throwable JavaDoc
145   {
146     return getLoaded().apply4 (arg1, arg2, arg3, arg4);
147   }
148
149   public Object JavaDoc applyN (Object JavaDoc[] args) throws Throwable JavaDoc
150   {
151     if (loaded == null)
152       load ();
153     if (loaded instanceof AutoloadProcedure)
154       throw new InternalError JavaDoc("circularity in autoload of "+getName());
155     return loaded.applyN (args);
156   }
157
158   public Procedure getSetter()
159   {
160     if (loaded == null)
161       load ();
162     if (loaded instanceof HasSetter)
163       return loaded.getSetter();
164     return super.getSetter();
165   }
166
167   public void writeExternal(ObjectOutput out) throws IOException
168   {
169     out.writeObject(getName());
170     out.writeObject(className);
171   }
172
173   public void readExternal(ObjectInput in)
174     throws IOException, ClassNotFoundException JavaDoc
175   {
176     setName((String JavaDoc) in.readObject());
177     className = (String JavaDoc) in.readObject();
178   }
179
180   public Object JavaDoc getProperty(Object JavaDoc key, Object JavaDoc defaultValue)
181   {
182     Object JavaDoc value = super.getProperty(key, null);
183     if (value != null)
184       return value;
185     return getLoaded().getProperty(key, defaultValue);
186   }
187 }
188
Popular Tags