KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > expr > ModuleInfo


1 // Copyright (c) 2006 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.expr;
5 import gnu.mapping.*;
6 import gnu.bytecode.*;
7 import gnu.kawa.reflect.FieldLocation;
8 import gnu.text.*;
9
10 public class ModuleInfo
11 {
12   /** Next element in list head by {@link ModuleManager#modules}. */
13   public ModuleInfo nextModule () { return next; }
14   ModuleInfo next;
15
16   /** Name of class that implements module.
17    * Must be non-null unless we're currently compiling the module,
18    * in which case sourcePath and comp must both be non-null.
19    */

20   public String JavaDoc className;
21
22   public Class JavaDoc moduleClass;
23
24   /** The namespace URI associated with this module, or {@code null}.
25    * This is null for Scheme modules, but non-null for XQuery modules.
26    */

27   public String JavaDoc getNamespaceUri () { return uri; }
28   public void setNamespaceUri (String JavaDoc uri) { this.uri = uri; }
29   String JavaDoc uri;
30
31   ModuleExp exp;
32   Compilation comp;
33
34   public Compilation getCompilation() { return comp; }
35
36   public void setCompilation (Compilation comp)
37   {
38     comp.minfo = this;
39     this.comp = comp;
40     ModuleExp mod = comp.mainLambda;
41     this.exp = mod;
42     if (mod != null)
43       {
44         String JavaDoc fileName = mod.getFileName();
45         this.sourcePath = fileName;
46         this.sourceAbsPath = absPath(fileName);
47       }
48   }
49
50   public static String JavaDoc absPath (String JavaDoc path)
51   {
52     Object JavaDoc url;
53     try
54       {
55         url = URI_utils.toURL(path);
56       }
57     catch (Throwable JavaDoc ex)
58       {
59         throw WrappedException.wrapIfNeeded(ex);
60       }
61     /* #ifdef use:java.net.URI */
62     try
63       {
64         url = URI_utils.toURI(url).normalize();
65       }
66     catch (Throwable JavaDoc ex)
67       {
68       }
69     /* #endif */
70     return url.toString();
71   }
72   
73   ModuleInfo[] dependencies;
74   int numDependencies;
75
76   /** Location of source for module, if known.
77    * This is an absolute URI, absolute filename,
78    * or filename relative to current working directory.
79    * Null if source not known; in that case className must be non-null.
80    */

81   public String JavaDoc sourcePath;
82   public String JavaDoc sourceAbsPath;
83
84   public long lastCheckedTime;
85   public long lastModifiedTime;
86
87   public synchronized void addDependency (ModuleInfo dep)
88   {
89     if (dependencies == null)
90       dependencies = new ModuleInfo[8];
91     else if (numDependencies == dependencies.length)
92       {
93         ModuleInfo[] deps = new ModuleInfo[2 * numDependencies];
94         System.arraycopy(dependencies, 0, deps, 0, numDependencies);
95         dependencies = deps;
96       }
97     dependencies[numDependencies++] = dep;
98   }
99
100   public ClassType getClassType ()
101   {
102     if (moduleClass != null)
103       return (ClassType) Type.make(moduleClass);
104     if (comp != null && comp.mainClass != null)
105       return comp.mainClass;
106     return ClassType.make(className);
107   }
108
109   public synchronized ModuleExp getModuleExp ()
110   {
111     ModuleExp m = exp;
112     if (m == null)
113       {
114         if (comp != null)
115           return comp.mainLambda;
116         ClassType ctype = ClassType.make(className);
117         m = new ModuleExp();
118         m.type = ctype;
119         m.setName(ctype.getName());
120         m.flags |= ModuleExp.LAZY_DECLARATIONS;
121         m.info = this;
122         exp = m;
123       }
124     return m;
125   }
126
127   /** If module has LAZY_DECLARATIONS, fix that. */
128   public synchronized ModuleExp setupModuleExp ()
129   {
130     ModuleExp mod = getModuleExp();
131     if ((mod.flags & ModuleExp.LAZY_DECLARATIONS) == 0)
132       return mod;
133     mod.setFlag(false, ModuleExp.LAZY_DECLARATIONS);
134     ClassType type;
135     Class JavaDoc rclass;
136     if (moduleClass != null)
137       {
138         rclass = moduleClass;
139         type = (ClassType) Type.make(rclass);
140       }
141     else
142       {
143         type = ClassType.make(className);
144         rclass = type.getReflectClass();
145       }
146     Object JavaDoc instance = null;
147
148     Language language = Language.getDefaultLanguage();
149     for (Field fld = type.getFields(); fld != null; fld = fld.getNext())
150       {
151     int flags = fld.getFlags();
152     if ((flags & Access.PUBLIC) == 0)
153       continue;
154     try
155       {
156             if ((flags & Access.STATIC) == 0 && instance == null)
157               instance = getInstance();
158             Object JavaDoc fvalue = rclass.getField(fld.getName()).get(instance);
159
160             Declaration fdecl = language.declFromField(mod, fvalue, fld);
161             if ((flags & Access.FINAL) != 0
162                 && (! (fvalue instanceof gnu.mapping.Location)
163                     || fvalue instanceof FieldLocation))
164               fdecl.noteValue(new QuoteExp(fvalue));
165             else
166               fdecl.noteValue(null);
167       }
168     catch (Exception JavaDoc ex)
169       {
170         throw new WrappedException(ex);
171       }
172       }
173
174     for (Declaration fdecl = mod.firstDecl();
175          fdecl != null; fdecl = fdecl.nextDecl())
176       {
177         makeDeclInModule2(mod, fdecl);
178       }
179     return mod;
180   }
181
182   public Class JavaDoc getModuleClass ()
183     throws ClassNotFoundException JavaDoc
184   {
185     Class JavaDoc mclass = moduleClass;
186     if (mclass != null)
187       return mclass;
188     mclass = Class.forName(className);
189     moduleClass = mclass;
190     return mclass;
191   }
192
193   public static ModuleInfo findFromInstance (Object JavaDoc instance)
194   {
195     return ModuleContext.getContext().findFromInstance(instance);
196   }
197
198   public static ModuleInfo find (String JavaDoc className)
199   {
200     return ModuleManager.getInstance().findWithClassName(className);
201   }
202
203   public static ModuleInfo find (Type type)
204   {
205     ModuleInfo info = ModuleManager.getInstance().findWithClassName(type.getName());
206     if (type instanceof ObjectType && ((ObjectType) type).isExisting())
207       {
208         try
209           {
210             info.moduleClass = type.getReflectClass();
211           }
212         catch (Exception JavaDoc ex)
213           {
214           }
215       }
216     return info;
217   }
218
219   public static void register (Object JavaDoc instance)
220   {
221     ModuleInfo info = find(instance.getClass().getName());
222     ModuleContext.getContext().setInstance(info, instance);
223   }
224
225   public Object JavaDoc getInstance ()
226   {
227     return ModuleContext.getContext().findInstance(this);
228   }
229
230   public Object JavaDoc getRunInstance ()
231   {
232     Object JavaDoc inst = getInstance();
233     if (inst instanceof Runnable JavaDoc)
234       ((Runnable JavaDoc) inst).run();
235     return inst;
236   }
237
238   static void makeDeclInModule2 (ModuleExp mod, Declaration fdecl)
239   {
240     Object JavaDoc fvalue = fdecl.getConstantValue();
241     if (fvalue instanceof FieldLocation)
242       {
243     FieldLocation floc = (FieldLocation) fvalue;
244         Declaration vdecl = floc.getDeclaration();
245         ReferenceExp fref = new ReferenceExp(vdecl);
246         fdecl.setAlias(true);
247         fref.setDontDereference(true);
248         fref.setFlag(ReferenceExp.CREATE_FIELD_REFERENCE);
249         fdecl.setValue(fref);
250         if (vdecl.isProcedureDecl())
251           fdecl.setProcedureDecl(true);
252         if (vdecl.getFlag(Declaration.IS_SYNTAX))
253           fdecl.setSyntax();
254         if (! fdecl.getFlag(Declaration.STATIC_SPECIFIED))
255           {
256             ClassType vtype = floc.getDeclaringClass();
257             String JavaDoc vname = vtype.getName();
258             for (Declaration xdecl = mod.firstDecl();
259                  xdecl != null; xdecl = xdecl.nextDecl())
260               {
261                 if (vname.equals(xdecl.getType().getName())
262                     && xdecl.getFlag(Declaration.MODULE_REFERENCE))
263                   {
264                     fref.setContextDecl(xdecl);
265                     break;
266                   }
267               }
268           }
269       }
270   }
271
272   public int getState () { return comp == null ? Compilation.CLASS_WRITTEN : comp.getState(); }
273
274   public void loadByStages (int wantedState)
275   {
276     int state = getState();
277     if (state + 1 >= wantedState)
278       return;
279     loadByStages(wantedState - 2);
280     state = getState();
281     if (state >= wantedState) // Most likely? if ERROR_SEEN.
282
return;
283     comp.setState(state+1);
284     int ndeps = numDependencies;
285     for (int idep = 0; idep < ndeps; idep++)
286       {
287         ModuleInfo dep = dependencies[idep];
288         dep.loadByStages(wantedState);
289       }
290     state = getState();
291     if (state >= wantedState) // Most likely? if ERROR_SEEN.
292
return;
293     comp.setState(state & ~1);
294     comp.process(wantedState);
295   }
296
297   /** Eagerly process the module and dependencies.
298    * @return true on success; false if we were unable to because of
299    * an error or a cyclic dependency.
300    */

301   public boolean loadEager (int wantedState)
302   {
303     if (comp == null && className != null)
304       return false;
305     int state = getState();
306     if (state >= wantedState)
307       return true;
308     if ((state & 1) != 0)
309       return false;
310     comp.setState(state + 1);
311     int ndeps = numDependencies;
312     for (int idep = 0; idep < ndeps; idep++)
313       {
314         ModuleInfo dep = dependencies[idep];
315         if (! dep.loadEager(wantedState))
316           {
317             if (getState() == state+1)
318               comp.setState(state);
319             return false;
320           }
321       }
322     if (getState() == state+1)
323       comp.setState(state);
324     comp.process(wantedState);
325     return getState() == wantedState;
326   }
327
328   public void clearClass ()
329   {
330     moduleClass = null;
331     numDependencies = 0;
332     dependencies = null;
333   }
334
335   /** Check if this module and its dependencies are up-to-dete.
336    * Only checks the sourcePath's modification time if it is at least
337    * ModifiedCacheTime since last time we checked.
338    * As as side-effects update lastModifiedTime and lastCheckedTime.
339    */

340   public boolean checkCurrent (ModuleManager manager, long now)
341   {
342     if (lastCheckedTime + manager.lastModifiedCacheTime >= now)
343       return true;
344     lastCheckedTime = now;
345     long lastModifiedTime = URI_utils.lastModified(sourceAbsPath);
346     if (moduleClass == null && className != null)
347       {
348         try
349           {
350             /* #ifdef JAVA2 */
351             moduleClass = Class.forName(className, false,
352                                         manager.defaultClassLoader);
353             /* #else */
354             // moduleClass = Class.forName(className);
355
/* #endif */
356           }
357         catch (ClassNotFoundException JavaDoc ex)
358           {
359             this.lastModifiedTime = lastModifiedTime;
360             return false;
361           }
362       }
363     if (this.lastModifiedTime == 0 && moduleClass != null)
364       {
365         String JavaDoc classFilename = className;
366         int dot = classFilename.lastIndexOf('.');
367         if (dot >= 0)
368           classFilename = classFilename.substring(dot+1);
369         classFilename = classFilename + ".class";
370         java.net.URL JavaDoc resource = moduleClass.getResource(classFilename);
371         if (resource != null)
372           {
373             try
374               {
375                 this.lastModifiedTime = resource.openConnection().getLastModified();
376               }
377             catch (java.io.IOException JavaDoc ex)
378               {
379                 resource = null;
380               }
381           }
382         if (resource == null)
383           {
384             // Couldn't open timestand of the .class file.
385
// Assume it is current.
386
this.lastModifiedTime = lastModifiedTime;
387             return true;
388           }
389       }
390     if (className == null || lastModifiedTime > this.lastModifiedTime)
391       {
392         moduleClass = null;
393         this.lastModifiedTime = lastModifiedTime;
394         return false;
395       }
396     for (int i = numDependencies; --i >= 0; )
397       {
398         ModuleInfo dep = dependencies[i];
399         if (! dep.checkCurrent(manager, now))
400           return false;
401       }
402     return true;
403   }
404
405   public String JavaDoc toString ()
406   {
407     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
408     sbuf.append("ModuleInfo[");
409     if (moduleClass != null)
410       {
411         sbuf.append("class: ");
412         sbuf.append(moduleClass);
413       }
414     else if (className != null)
415       {
416         sbuf.append("class-name: ");
417         sbuf.append(className);
418       }
419     sbuf.append(']');
420     return sbuf.toString();
421   }
422 }
423
Popular Tags