KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > expr > ModuleManager


1 package gnu.expr;
2 import java.net.*;
3 import gnu.bytecode.ClassType;
4 import gnu.text.URI_utils;
5 import gnu.mapping.CallContext;
6
7 /** A database of known modules as represented by {@link ModuleInfo}..
8  * Current there is only a single global instanceof {@code ModuleManager};
9  * in the future each different "applications" may have their own.
10  */

11
12 public class ModuleManager
13 {
14   public ClassLoader JavaDoc defaultClassLoader = ClassLoader.getSystemClassLoader();
15
16   private String JavaDoc compilationDirectory = "";
17   public void setCompilationDirectory (String JavaDoc path)
18   {
19     if (path == null)
20       path = "";
21     int plen = path.length();
22     if (plen > 0)
23       {
24         char sep = java.io.File.separatorChar; // Or '/' if path is a URL??
25
if (path.charAt(plen - 1) != sep)
26           path = path + sep;
27       }
28     compilationDirectory = path;
29   }
30   public String JavaDoc getCompilationDirectory () { return compilationDirectory; }
31
32   static ModuleManager instance = new ModuleManager();
33
34   /** For now assumes a single global ModuleManager.
35    * Later, might have multiple managers. */

36   public static ModuleManager getInstance() { return instance; }
37
38   public static final long LAST_MODIFIED_CACHE_TIME = 1000;
39   /** Number millseconds before we re-check file's modified time. */
40   public long lastModifiedCacheTime = LAST_MODIFIED_CACHE_TIME;
41
42   /** Chain of all modules managed by this ModuleManager.
43    * Linked together by ModuleInfo's next field. */

44   ModuleInfo modules;
45   public ModuleInfo firstModule () { return modules; }
46
47   public ModuleInfo find (Compilation comp)
48   {
49     ModuleExp mexp = comp.getModule();
50     ClassType ctype = mexp.classFor(comp);
51     ModuleInfo info = findWithClassName(ctype.getName());
52     info.setCompilation(comp);
53     return info;
54   }
55
56   public void add (ModuleInfo info)
57   {
58     info.next = modules;
59     modules = info;
60   }
61
62   public ModuleInfo searchWithClassName (String JavaDoc className)
63   {
64     for (ModuleInfo info = modules; info != null; info = info.next)
65       if (className.equals(info.className))
66         return info;
67     return null;
68   }
69
70   public synchronized ModuleInfo findWithClassName (String JavaDoc className)
71   {
72     ModuleInfo info = searchWithClassName(className);
73     if (info == null)
74       {
75         info = new ModuleInfo();
76         info.className = className;
77         add(info);
78       }
79     return info;
80   }
81
82   private ModuleInfo searchWithAbsSourcePath (String JavaDoc sourcePath)
83   {
84     for (ModuleInfo info = modules; info != null; info = info.next)
85       if (sourcePath.equals(info.sourceAbsPath))
86         return info;
87     return null;
88   }
89
90   public synchronized ModuleInfo findWithSourcePath (String JavaDoc sourcePath)
91   {
92     String JavaDoc sourceAbsPath = ModuleInfo.absPath(sourcePath);
93     ModuleInfo info = searchWithAbsSourcePath(sourceAbsPath);
94     if (info == null)
95       {
96         info = new ModuleInfo();
97         info.sourcePath = sourcePath;
98         info.sourceAbsPath = sourceAbsPath;
99         add(info);
100       }
101     return info;
102   }
103
104   public ModuleInfo findWithURL (URL url)
105   {
106     return findWithSourcePath(url.toExternalForm());
107   }
108
109   /** Called by compiler-generated code.
110    * The compiler generates in each package a class that extends
111    * {@link ModuleSet}, and that contains a
112    * {@link ModuleSet#register(ModuleManager)} method that calls
113    * back to this method. This method then registers the specified module.
114    */

115   public void register (String JavaDoc moduleClass, String JavaDoc moduleSource, String JavaDoc moduleUri)
116   {
117     // Unclear what is the right thing to do a we have an existing module
118
// with the same source or class name. One case is when we're explicitly
119
// compiling a source file and (in XQuery) importing (other) modules in the
120
// same namespace. In that case the file we're compiling should take
121
// precedence over old data in the packages's existing $ModulesMap$ class.
122
if (searchWithClassName(moduleClass) != null)
123       return;
124     if (searchWithAbsSourcePath(ModuleInfo.absPath(moduleSource)) != null)
125       return;
126     ModuleInfo info = new ModuleInfo();
127     if (gnu.text.URI_utils.isAbsolute(moduleSource))
128       info.sourceAbsPath = moduleSource;
129     else
130       {
131         // Resolve moduleSource against moduleClass path.
132
try
133           {
134             // See comment in loadPackageInfo.
135
Class JavaDoc setClass = this.packageInfoChain.getClass();
136             String JavaDoc setClassName = setClass.getName().replace('.', '/')+".class";
137             java.net.URL JavaDoc setClassURL
138               = setClass.getClassLoader().getResource(setClassName);
139             Object JavaDoc moduleURI = URI_utils.resolve(moduleSource, setClassURL);
140             info.sourceAbsPath = moduleURI.toString();
141           }
142         catch (Throwable JavaDoc ex)
143           {
144             return;
145           }
146       }
147     info.className = moduleClass;
148     info.sourcePath = moduleSource;
149     info.uri = moduleUri;
150     add(info);
151   }
152
153   /** List of {@link ModuleSet}s registered with this {@code ModuleManager}. */
154   ModuleSet packageInfoChain;
155
156   /** Search for and if needed load the {@link ModuleSet} for a package.
157    */

158   public synchronized void loadPackageInfo (String JavaDoc packageName)
159     throws ClassNotFoundException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc
160   {
161     String JavaDoc moduleSetClassName = packageName + "." + ModuleSet.MODULES_MAP;
162
163     for (ModuleSet set = packageInfoChain; set != null; set = set.next)
164       {
165         String JavaDoc setName = set.getClass().getName();
166         if (setName.equals(moduleSetClassName))
167           continue;
168       }
169     Class JavaDoc setClass = Class.forName(moduleSetClassName);
170     ModuleSet instance = (ModuleSet) setClass.newInstance();
171
172     instance.next = this.packageInfoChain;
173     // The ModuleInfo.register method depends on packageInfoChain being
174
// the current ModuleSet. Bit of a kludge.
175
this.packageInfoChain = instance;
176     instance.register(this);
177   }
178
179   /** Reset the set of known modules. */
180   public void clear ()
181   {
182     // Clear modules and packageIndoChain lists.
183
// We also clean the 'next' fields, to avoid leaks if
184
// somethings happens to be pointing at a ModuleInto or ModuleSet.
185
// This may be overkill.
186
ModuleSet set = packageInfoChain;
187     while (set != null)
188       {
189         ModuleSet next = set.next;
190         set.next = null;
191         set = next;
192       }
193     packageInfoChain = null;
194
195     ModuleInfo module = modules;
196     while (module != null)
197       {
198         ModuleInfo next = module.next;
199         module.next = null;
200         module = next;
201       }
202     modules = null;
203   }
204 }
205
Popular Tags