KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > dev > cfg > ModuleDefLoader


1 /*
2  * Copyright 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.dev.cfg;
17
18 import com.google.gwt.core.ext.TreeLogger;
19 import com.google.gwt.core.ext.UnableToCompleteException;
20 import com.google.gwt.dev.util.Util;
21 import com.google.gwt.dev.util.xml.ReflectiveParser;
22 import com.google.gwt.util.tools.Utility;
23
24 import java.io.File JavaDoc;
25 import java.io.Reader JavaDoc;
26 import java.net.URI JavaDoc;
27 import java.net.URISyntaxException JavaDoc;
28 import java.net.URL JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Set JavaDoc;
34
35 /**
36  * The top-level API for loading module XML.
37  */

38 public class ModuleDefLoader {
39
40   // Should always be true. If it is false complete type oracle analysis and
41
// bytecode cache reload will occur on each reload.
42
private static boolean enableCachingModules = true;
43   private static final Set JavaDoc forceInherits = new HashSet JavaDoc();
44   private static final Map JavaDoc loadedModules = new HashMap JavaDoc();
45
46   /**
47    * Forces all modules loaded via subsequent calls to
48    * {@link #loadFromClassPath(TreeLogger, String)} to automatically inherit the
49    * specified module. If this method is called multiple times, the order of
50    * inclusion is unspecified.
51    *
52    * @param moduleName The module all subsequently loaded modules should inherit
53    * from.
54    */

55   public static void forceInherit(String JavaDoc moduleName) {
56     forceInherits.add(moduleName);
57   }
58
59   /**
60    * Gets whether module caching is enabled.
61    *
62    * @return <code>true</code> if module cachine is enabled, otherwise
63    * <code>false</code>.
64    */

65   public static boolean getEnableCachingModules() {
66     return enableCachingModules;
67   }
68
69   /**
70    * Loads a new module from the class path.
71    *
72    * @param logger Logs the process.
73    * @param moduleName The module to load.
74    * @return The loaded module.
75    * @throws UnableToCompleteException
76    */

77   public static ModuleDef loadFromClassPath(TreeLogger logger, String JavaDoc moduleName)
78       throws UnableToCompleteException {
79     ModuleDef moduleDef = (ModuleDef) loadedModules.get(moduleName);
80     if (moduleDef == null || moduleDef.isGwtXmlFileStale()) {
81       moduleDef = new ModuleDefLoader().load(logger, moduleName);
82       if (enableCachingModules) {
83         loadedModules.put(moduleName, moduleDef);
84       }
85     } else {
86       moduleDef.refresh(logger);
87     }
88     return moduleDef;
89   }
90
91   /**
92    * Enables or disables caching loaded modules for subsequent requests.
93    *
94    * @param enableCachingModules If <code>true</code> subsequent calls to
95    * {@link #loadFromClassPath(TreeLogger, String)} will cause the
96    * resulting module to be cached. If <code>false</code> such
97    * modules will not be cached.
98    */

99   public static void setEnableCachingModules(boolean enableCachingModules) {
100     ModuleDefLoader.enableCachingModules = enableCachingModules;
101   }
102
103   private final Set JavaDoc alreadyLoadedModules = new HashSet JavaDoc();
104
105   private final ClassLoader JavaDoc classLoader;
106
107   private ModuleDefLoader() {
108     this.classLoader = Thread.currentThread().getContextClassLoader();
109   }
110
111   /**
112    * Loads a new module into <code>moduleDef</code> as an included module.
113    *
114    * @param logger Logs the process.
115    * @param moduleName The module to load.
116    * @param moduleDef The module to add the new module to.
117    * @throws UnableToCompleteException
118    */

119   void nestedLoad(TreeLogger logger, String JavaDoc moduleName, ModuleDef moduleDef)
120       throws UnableToCompleteException {
121
122     if (alreadyLoadedModules.contains(moduleName)) {
123       logger.log(TreeLogger.TRACE, "Module '" + moduleName
124           + "' has already been loaded and will be skipped", null);
125       return;
126     } else {
127       alreadyLoadedModules.add(moduleName);
128     }
129
130     // Find the specified module using the classpath.
131
//
132
String JavaDoc slashedModuleName = moduleName.replace('.', '/');
133     String JavaDoc resName = slashedModuleName + ".gwt.xml";
134     URL JavaDoc moduleURL = classLoader.getResource(resName);
135
136     if (moduleURL != null) {
137       String JavaDoc externalForm = moduleURL.toExternalForm();
138       logger.log(TreeLogger.TRACE, "Module location: " + externalForm, null);
139       try {
140         if ((!(externalForm.startsWith("jar:file")))
141             && (!(externalForm.startsWith("zip:file")))
142             && (!(externalForm.startsWith("http://")))
143             && (!(externalForm.startsWith("ftp://")))) {
144           File JavaDoc gwtXmlFile = new File JavaDoc(new URI JavaDoc(externalForm));
145           moduleDef.addGwtXmlFile(gwtXmlFile);
146         }
147       } catch (URISyntaxException JavaDoc e) {
148         logger.log(TreeLogger.ERROR, "Error parsing URI", e);
149         throw new UnableToCompleteException();
150       }
151     }
152     if (moduleURL == null) {
153       String JavaDoc msg = "Unable to find '"
154           + resName
155           + "' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?";
156       logger.log(TreeLogger.ERROR, msg, null);
157       throw new UnableToCompleteException();
158     }
159
160     // Extract just the directory containing the module.
161
//
162
String JavaDoc moduleDir = "";
163     int i = slashedModuleName.lastIndexOf('/');
164     if (i != -1) {
165       moduleDir = slashedModuleName.substring(0, i) + "/";
166     }
167
168     // Parse it.
169
//
170
Reader JavaDoc r = null;
171     try {
172       r = Util.createReader(logger, moduleURL);
173       ModuleDefSchema schema = new ModuleDefSchema(logger, this, moduleURL,
174           moduleDir, moduleDef);
175       ReflectiveParser.parse(logger, schema, r);
176     } finally {
177       Utility.close(r);
178     }
179   }
180
181   /**
182    *
183    * This method loads a module.
184    *
185    * @param logger used to log the loading process
186    * @param moduleName the name of the module
187    * @return the module returned -- cannot be null
188    * @throws UnableToCompleteException if module loading failed.
189    */

190   private ModuleDef load(TreeLogger logger, String JavaDoc moduleName)
191       throws UnableToCompleteException {
192     logger = logger.branch(TreeLogger.TRACE, "Loading module '" + moduleName
193         + "'", null);
194
195     if (!ModuleDef.isValidModuleName(moduleName)) {
196       logger.log(TreeLogger.ERROR, "Invalid module name: '" + moduleName + "'",
197           null);
198       throw new UnableToCompleteException();
199     }
200
201     ModuleDef moduleDef = new ModuleDef(moduleName);
202     for (Iterator JavaDoc it = forceInherits.iterator(); it.hasNext();) {
203       String JavaDoc forceInherit = (String JavaDoc) it.next();
204       TreeLogger branch = logger.branch(TreeLogger.TRACE,
205           "Loading forceably inherited module '" + forceInherit + "'", null);
206       nestedLoad(branch, forceInherit, moduleDef);
207     }
208     nestedLoad(logger, moduleName, moduleDef);
209
210     // Do any final setup.
211
//
212
moduleDef.normalize(logger);
213
214     return moduleDef;
215   }
216 }
217
Popular Tags