1 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.core.ext.typeinfo.CompilationUnitProvider; 21 import com.google.gwt.core.ext.typeinfo.TypeOracle; 22 import com.google.gwt.dev.jdt.CacheManager; 23 import com.google.gwt.dev.jdt.TypeOracleBuilder; 24 import com.google.gwt.dev.jdt.URLCompilationUnitProvider; 25 import com.google.gwt.dev.util.Empty; 26 import com.google.gwt.dev.util.FileOracle; 27 import com.google.gwt.dev.util.FileOracleFactory; 28 import com.google.gwt.dev.util.Util; 29 import com.google.gwt.dev.util.FileOracleFactory.FileFilter; 30 31 import org.apache.tools.ant.types.ZipScanner; 32 33 import java.io.File ; 34 import java.net.URL ; 35 import java.util.ArrayList ; 36 import java.util.Arrays ; 37 import java.util.Comparator ; 38 import java.util.HashMap ; 39 import java.util.HashSet ; 40 import java.util.Iterator ; 41 import java.util.List ; 42 import java.util.Map ; 43 import java.util.Set ; 44 import java.util.Map.Entry; 45 46 50 public class ModuleDef { 51 52 private static final FileFilter JAVA_ACCEPTOR = new FileFilter() { 53 public boolean accept(String name) { 54 return name.endsWith(".java"); 55 } 56 }; 57 58 private static final Comparator REV_NAME_CMP = new Comparator () { 59 public int compare(Object o1, Object o2) { 60 Map.Entry entry1 = (Entry) o1; 61 Map.Entry entry2 = (Entry) o2; 62 String key1 = (String ) entry1.getKey(); 63 String key2 = (String ) entry2.getKey(); 64 return key2.compareTo(key1); 66 } 67 }; 68 69 public static boolean isValidModuleName(String moduleName) { 70 String [] parts = moduleName.split("\\."); 71 for (int i = 0; i < parts.length; i++) { 72 String part = parts[i]; 73 if (!Util.isValidJavaIdent(part)) { 74 return false; 75 } 76 } 77 return true; 78 } 79 80 private final ArrayList allCups = new ArrayList (); 81 82 private final Set alreadySeenFiles = new HashSet (); 83 84 private final CacheManager cacheManager = new CacheManager(".gwt-cache", 85 new TypeOracle()); 86 87 private CompilationUnitProvider[] cups = new CompilationUnitProvider[0]; 88 89 private final List entryPointTypeNames = new ArrayList (); 90 91 private final Set gwtXmlFiles = new HashSet (); 92 93 private FileOracle lazyPublicOracle; 94 95 private FileOracle lazySourceOracle; 96 97 private TypeOracle lazyTypeOracle; 98 99 private final long moduleDefCreationTime = System.currentTimeMillis(); 100 101 private final String name; 102 103 private final Properties properties = new Properties(); 104 105 private final FileOracleFactory publicPathEntries = new FileOracleFactory(); 106 107 private final Rules rules = new Rules(); 108 109 private final Scripts scripts = new Scripts(); 110 111 private final Map servletClassNamesByPath = new HashMap (); 112 113 private final FileOracleFactory sourcePathEntries = new FileOracleFactory(); 114 115 private final Styles styles = new Styles(); 116 117 public ModuleDef(String name) { 118 this.name = name; 119 } 120 121 public synchronized void addEntryPointTypeName(String typeName) { 122 entryPointTypeNames.add(typeName); 123 } 124 125 public void addGwtXmlFile(File xmlFile) { 126 gwtXmlFiles.add(xmlFile); 127 } 128 129 public synchronized void addPublicPackage(String publicPackage, 130 String [] includeList, String [] excludeList, boolean defaultExcludes, 131 boolean caseSensitive) { 132 133 if (lazyPublicOracle != null) { 134 throw new IllegalStateException ("Already normalized"); 135 } 136 137 142 final ZipScanner scanner = new ZipScanner(); 143 if (includeList.length > 0) { 144 scanner.setIncludes(includeList); 145 } 146 if (excludeList.length > 0) { 147 scanner.setExcludes(excludeList); 148 } 149 if (defaultExcludes) { 150 scanner.addDefaultExcludes(); 151 } 152 scanner.setCaseSensitive(caseSensitive); 153 scanner.init(); 154 155 publicPathEntries.addRootPackage(publicPackage, new FileFilter() { 157 public boolean accept(String name) { 158 return scanner.match(name); 159 } 160 }); 161 } 162 163 public synchronized void addSourcePackage(String sourcePackage) { 164 if (lazySourceOracle != null) { 165 throw new IllegalStateException ("Already normalized"); 166 } 167 168 sourcePathEntries.addPackage(sourcePackage, JAVA_ACCEPTOR); 170 } 171 172 public synchronized void addSuperSourcePackage(String superSourcePackage) { 173 if (lazySourceOracle != null) { 174 throw new IllegalStateException ("Already normalized"); 175 } 176 177 sourcePathEntries.addRootPackage(superSourcePackage, JAVA_ACCEPTOR); 179 } 180 181 public void clearEntryPoints() { 182 entryPointTypeNames.clear(); 183 } 184 185 public synchronized URL findPublicFile(String partialPath) { 186 return lazyPublicOracle.find(partialPath); 187 } 188 189 public synchronized String findServletForPath(String actual) { 190 Set entrySet = servletClassNamesByPath.entrySet(); 193 Map.Entry [] entries = (Entry[]) Util.toArray(Map.Entry .class, entrySet); 194 Arrays.sort(entries, REV_NAME_CMP); 195 for (int i = 0, n = entries.length; i < n; ++i) { 196 String mapping = (String ) entries[i].getKey(); 197 203 if (actual.equals(mapping) || actual.startsWith(mapping + "/")) { 204 return (String ) entries[i].getValue(); 205 } 206 } 207 return null; 208 } 209 210 public String [] getAllPublicFiles() { 211 return lazyPublicOracle.getAllFiles(); 212 } 213 214 public CacheManager getCacheManager() { 215 return cacheManager; 216 } 217 218 public synchronized CompilationUnitProvider[] getCompilationUnits() { 219 return cups; 220 } 221 222 public synchronized String [] getEntryPointTypeNames() { 223 final int n = entryPointTypeNames.size(); 224 return (String []) entryPointTypeNames.toArray(new String [n]); 225 } 226 227 public synchronized String getFunctionName() { 228 return name.replace('.', '_'); 229 } 230 231 public synchronized String getName() { 232 return name; 233 } 234 235 238 public synchronized Properties getProperties() { 239 return properties; 240 } 241 242 245 public synchronized Rules getRules() { 246 return rules; 247 } 248 249 252 public Scripts getScripts() { 253 return scripts; 254 } 255 256 public synchronized String [] getServletPaths() { 257 return (String []) servletClassNamesByPath.keySet().toArray(Empty.STRINGS); 258 } 259 260 263 public Styles getStyles() { 264 return styles; 265 } 266 267 public synchronized TypeOracle getTypeOracle(TreeLogger logger) 268 throws UnableToCompleteException { 269 if (lazyTypeOracle == null) { 270 271 try { 274 String msg = "Analyzing source in module '" + name + "'"; 275 TreeLogger branch = logger.branch(TreeLogger.TRACE, msg, null); 276 long before = System.currentTimeMillis(); 277 TypeOracleBuilder builder = new TypeOracleBuilder(getCacheManager()); 278 CompilationUnitProvider[] currentCups = getCompilationUnits(); 279 Arrays.sort(currentCups, CompilationUnitProvider.LOCATION_COMPARATOR); 280 281 TreeLogger subBranch = null; 282 if (branch.isLoggable(TreeLogger.DEBUG)) { 283 subBranch = branch.branch(TreeLogger.DEBUG, 284 "Adding compilation units...", null); 285 } 286 287 for (int i = 0; i < currentCups.length; i++) { 288 CompilationUnitProvider cup = currentCups[i]; 289 if (subBranch != null) { 290 subBranch.log(TreeLogger.DEBUG, cup.getLocation(), null); 291 } 292 builder.addCompilationUnit(currentCups[i]); 293 } 294 lazyTypeOracle = builder.build(branch); 295 long after = System.currentTimeMillis(); 296 branch.log(TreeLogger.TRACE, "Finished in " + (after - before) + " ms", 297 null); 298 } catch (UnableToCompleteException e) { 299 logger.log(TreeLogger.ERROR, "Failed to complete analysis", null); 300 throw new UnableToCompleteException(); 301 } 302 303 boolean seedTypesMissing = false; 306 if (lazyTypeOracle.findType("java.lang.Object") == null) { 307 Util.logMissingTypeErrorWithHints(logger, "java.lang.Object"); 308 seedTypesMissing = true; 309 } else { 310 TreeLogger branch = logger.branch(TreeLogger.TRACE, 311 "Finding entry point classes", null); 312 String [] typeNames = getEntryPointTypeNames(); 313 for (int i = 0; i < typeNames.length; i++) { 314 String typeName = typeNames[i]; 315 if (lazyTypeOracle.findType(typeName) == null) { 316 Util.logMissingTypeErrorWithHints(branch, typeName); 317 seedTypesMissing = true; 318 } 319 } 320 } 321 322 if (seedTypesMissing) { 323 throw new UnableToCompleteException(); 324 } 325 } 326 327 return lazyTypeOracle; 328 } 329 330 public boolean isGwtXmlFileStale() { 331 for (Iterator iter = gwtXmlFiles.iterator(); iter.hasNext();) { 332 File xmlFile = (File ) iter.next(); 333 if ((!xmlFile.exists()) 334 || (xmlFile.lastModified() > moduleDefCreationTime)) { 335 return true; 336 } 337 } 338 return false; 339 } 340 341 349 public synchronized void mapServlet(String path, String servletClassName) { 350 servletClassNamesByPath.put(path, servletClassName); 351 } 352 353 public synchronized void refresh(TreeLogger logger) 354 throws UnableToCompleteException { 355 356 cacheManager.invalidateVolatileFiles(); 357 lazyTypeOracle = null; 358 normalize(logger); 359 getTypeOracle(logger); 360 Util.invokeInaccessableMethod(TypeOracle.class, "incrementReloadCount", 361 new Class [] {}, lazyTypeOracle, new Object [] {}); 362 } 363 364 371 synchronized void normalize(TreeLogger logger) { 372 for (Iterator iter = getProperties().iterator(); iter.hasNext();) { 375 Property prop = (Property) iter.next(); 376 if (prop.getActiveValue() == null) { 377 String [] knownValues = prop.getKnownValues(); 381 assert (knownValues.length > 0); 382 if (knownValues.length > 1) { 383 if (prop.getProvider() == null) { 384 prop.setProvider(new DefaultPropertyProvider(this, prop)); 387 } 388 } else { 389 prop.setActiveValue(knownValues[0]); 390 } 391 } 392 } 393 394 TreeLogger branch = Messages.SOURCE_PATH_LOCATIONS.branch(logger, null); 397 lazySourceOracle = sourcePathEntries.create(branch); 398 399 if (lazySourceOracle.isEmpty()) { 400 branch.log(TreeLogger.WARN, 401 "No source path entries; expect subsequent failures", null); 402 } else { 403 String [] allFiles = lazySourceOracle.getAllFiles(); 405 Set files = new HashSet (); 406 files.addAll(Arrays.asList(allFiles)); 407 files.removeAll(alreadySeenFiles); 408 for (Iterator iter = files.iterator(); iter.hasNext();) { 409 String fileName = (String ) iter.next(); 410 int pos = fileName.lastIndexOf('/'); 411 String packageName; 412 if (pos >= 0) { 413 packageName = fileName.substring(0, pos); 414 packageName = packageName.replace('/', '.'); 415 } else { 416 packageName = ""; 417 } 418 URL url = lazySourceOracle.find(fileName); 419 allCups.add(new URLCompilationUnitProvider(url, packageName)); 420 } 421 alreadySeenFiles.addAll(files); 422 this.cups = (CompilationUnitProvider[]) allCups.toArray(this.cups); 423 } 424 425 branch = Messages.PUBLIC_PATH_LOCATIONS.branch(logger, null); 428 lazyPublicOracle = publicPathEntries.create(branch); 429 } 430 431 } 432 | Popular Tags |