Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.cfg;
import com.google.gwt.core.ext.Linker;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompilationStateBuilder;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.resource.ResourceOracle;
import com.google.gwt.dev.resource.impl.DefaultFilters;
import com.google.gwt.dev.resource.impl.PathPrefix;
import com.google.gwt.dev.resource.impl.PathPrefixSet;
import com.google.gwt.dev.resource.impl.ResourceFilter;
import com.google.gwt.dev.resource.impl.ResourceOracleImpl;
import com.google.gwt.dev.util.Empty;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* Represents a module specification. In principle, this could be built without
* XML for unit tests.
*/
public class ModuleDef {
private static final ResourceFilter NON_JAVA_RESOURCES = new ResourceFilter() {
public boolean allows(String path) {
return !path.endsWith(".java") && !path.endsWith(".class");
}
};
private static final Comparator> REV_NAME_CMP = new Comparator>() {
public int compare(Map.Entry entry1, Map.Entry entry2) {
String key1 = entry1.getKey();
String key2 = entry2.getKey();
// intentionally reversed
return key2.compareTo(key1);
}
};
public static boolean isValidModuleName(String moduleName) {
String[] parts = moduleName.split("\\.");
for (int i = 0; i < parts.length; i++) {
String part = parts[i];
if (!Util.isValidJavaIdent(part)) {
return false;
}
}
return true;
}
private final Set activeLinkers = new LinkedHashSet();
private String activePrimaryLinker;
private boolean collapseAllProperties;
private final DefaultFilters defaultFilters;
private final List entryPointTypeNames = new ArrayList();
private final Set gwtXmlFiles = new HashSet();
private ResourceOracleImpl lazyPublicOracle;
private ResourceOracleImpl lazyResourcesOracle;
private ResourceOracleImpl lazySourceOracle;
private final Map> linkerTypesByName = new LinkedHashMap>();
private final long moduleDefCreationTime = System.currentTimeMillis();
private final String name;
/**
* Must use a separate field to track override, because setNameOverride() will
* get called every time a module is inherited, but only the last one matters.
*/
private String nameOverride;
private boolean needsRefresh;
private final Properties properties = new Properties();
private PathPrefixSet publicPrefixSet = new PathPrefixSet();
private final Rules rules = new Rules();
private final Scripts scripts = new Scripts();
private final Map servletClassNamesByPath = new HashMap();
private PathPrefixSet sourcePrefixSet = new PathPrefixSet();
private final Styles styles = new Styles();
public ModuleDef(String name) {
this.name = name;
defaultFilters = new DefaultFilters();
}
public synchronized void addEntryPointTypeName(String typeName) {
entryPointTypeNames.add(typeName);
}
public void addGwtXmlFile(File xmlFile) {
gwtXmlFiles.add(xmlFile);
}
public void addLinker(String name) {
Class extends Linker> clazz = getLinker(name);
assert clazz != null;
LinkerOrder order = clazz.getAnnotation(LinkerOrder.class);
if (order.value() == Order.PRIMARY) {
if (activePrimaryLinker != null) {
activeLinkers.remove(activePrimaryLinker);
}
activePrimaryLinker = name;
}
activeLinkers.add(name);
}
public synchronized void addPublicPackage(String publicPackage,
String[] includeList, String[] excludeList, String[] skipList,
boolean defaultExcludes, boolean caseSensitive) {
if (lazyPublicOracle != null) {
throw new IllegalStateException("Already normalized");
}
publicPrefixSet.add(new PathPrefix(publicPackage,
defaultFilters.customResourceFilter(includeList, excludeList,
skipList, defaultExcludes, caseSensitive), true, excludeList));
}
public void addSourcePackage(String sourcePackage, String[] includeList,
String[] excludeList, String[] skipList, boolean defaultExcludes,
boolean caseSensitive) {
addSourcePackageImpl(sourcePackage, includeList, excludeList,
skipList, defaultExcludes, caseSensitive, false);
}
public void addSourcePackageImpl(String sourcePackage, String[] includeList,
String[] excludeList, String[] skipList, boolean defaultExcludes,
boolean caseSensitive, boolean isSuperSource) {
if (lazySourceOracle != null) {
throw new IllegalStateException("Already normalized");
}
PathPrefix pathPrefix = new PathPrefix(sourcePackage,
defaultFilters.customJavaFilter(includeList, excludeList, skipList,
defaultExcludes, caseSensitive), isSuperSource, excludeList);
sourcePrefixSet.add(pathPrefix);
}
public void addSuperSourcePackage(String superSourcePackage,
String[] includeList, String[] excludeList, String[] skipList,
boolean defaultExcludes, boolean caseSensitive) {
addSourcePackageImpl(superSourcePackage, includeList, excludeList,
skipList, defaultExcludes, caseSensitive, true);
}
/**
* Free up memory no longer needed in later compile stages. After calling this
* method, the ResourceOraclewill be empty and unusable. Calling
* {@link #refresh(TreeLogger)} will restore them.
*/
public synchronized void clear() {
if (lazySourceOracle != null) {
lazySourceOracle.clear();
}
rules.dispose();
}
public void clearEntryPoints() {
entryPointTypeNames.clear();
}
/**
* Associate a Linker class with a symbolic name. If the name had been
* previously assigned, this method will redefine the name. If the redefined
* linker had been previously added to the set of active linkers, the old
* active linker will be replaced with the new linker.
*/
public void defineLinker(TreeLogger logger, String name,
Class extends Linker> linker) throws UnableToCompleteException {
Class extends Linker> old = getLinker(name);
if (old != null) {
// Redefining an existing name
if (activePrimaryLinker.equals(name)) {
// Make sure the new one is also a primary linker
if (!linker.getAnnotation(LinkerOrder.class).value().equals(
Order.PRIMARY)) {
logger.log(TreeLogger.ERROR, "Redefining primary linker " + name
+ " with non-primary implementation " + linker.getName());
throw new UnableToCompleteException();
}
} else if (activeLinkers.contains(name)) {
// Make sure it's a not a primary linker
if (linker.getAnnotation(LinkerOrder.class).value().equals(
Order.PRIMARY)) {
logger.log(TreeLogger.ERROR, "Redefining non-primary linker " + name
+ " with primary implementation " + linker.getName());
throw new UnableToCompleteException();
}
}
}
linkerTypesByName.put(name, linker);
}
public synchronized Resource findPublicFile(String partialPath) {
doRefresh();
return lazyPublicOracle.getResourceMap().get(partialPath);
}
public synchronized String findServletForPath(String actual) {
// Walk in backwards sorted order to find the longest path match first.
Set> entrySet = servletClassNamesByPath.entrySet();
Entry[] entries = Util.toArray(Entry.class, entrySet);
Arrays.sort(entries, REV_NAME_CMP);
for (int i = 0, n = entries.length; i < n; ++i) {
String mapping = entries[i].getKey();
/*
* Ensure that URLs that match the servlet mapping, including those that
* have additional path_info, get routed to the correct servlet.
*
* See "Inside Servlets", Second Edition, pg. 208
*/
if (actual.equals(mapping) || actual.startsWith(mapping + "/")) {
return entries[i].getValue();
}
}
return null;
}
/**
* Returns the Resource for a source file if it is found; null
* otherwise.
*
* @param partialPath the partial path of the source file
* @return the resource for the requested source file
*/
public synchronized Resource findSourceFile(String partialPath) {
doRefresh();
return lazySourceOracle.getResourceMap().get(partialPath);
}
public Set getActiveLinkerNames() {
return new LinkedHashSet(activeLinkers);
}
public Set> getActiveLinkers() {
Set> toReturn = new LinkedHashSet>();
for (String linker : activeLinkers) {
assert linkerTypesByName.containsKey(linker) : linker;
toReturn.add(linkerTypesByName.get(linker));
}
return toReturn;
}
public Class extends Linker> getActivePrimaryLinker() {
assert linkerTypesByName.containsKey(activePrimaryLinker) : activePrimaryLinker;
return linkerTypesByName.get(activePrimaryLinker);
}
public String[] getAllPublicFiles() {
doRefresh();
return lazyPublicOracle.getPathNames().toArray(Empty.STRINGS);
}
/**
* Strictly for statistics gathering. There is no guarantee that the source
* oracle has been initialized.
*/
public String[] getAllSourceFiles() {
doRefresh();
return lazySourceOracle.getPathNames().toArray(Empty.STRINGS);
}
/**
* Returns the physical name for the module by which it can be found in the
* classpath.
*/
public String getCanonicalName() {
return name;
}
public synchronized CompilationState getCompilationState(TreeLogger logger)
throws UnableToCompleteException {
doRefresh();
CompilationState compilationState = CompilationStateBuilder.buildFrom(
logger, lazySourceOracle.getResources());
checkForSeedTypes(logger, compilationState);
return compilationState;
}
public synchronized String[] getEntryPointTypeNames() {
final int n = entryPointTypeNames.size();
return entryPointTypeNames.toArray(new String[n]);
}
public synchronized String getFunctionName() {
return getName().replace('.', '_');
}
public Class extends Linker> getLinker(String name) {
return linkerTypesByName.get(name);
}
public Map> getLinkers() {
return linkerTypesByName;
}
public synchronized String getName() {
return nameOverride != null ? nameOverride : name;
}
/**
* The properties that have been defined.
*/
public synchronized Properties getProperties() {
return properties;
}
public synchronized ResourceOracle getResourcesOracle() {
if (lazyResourcesOracle == null) {
lazyResourcesOracle = new ResourceOracleImpl(TreeLogger.NULL);
PathPrefixSet pathPrefixes = lazySourceOracle.getPathPrefixes();
PathPrefixSet newPathPrefixes = new PathPrefixSet();
for (PathPrefix pathPrefix : pathPrefixes.values()) {
newPathPrefixes.add(new PathPrefix(pathPrefix.getPrefix(),
NON_JAVA_RESOURCES, pathPrefix.shouldReroot()));
}
lazyResourcesOracle.setPathPrefixes(newPathPrefixes);
ResourceOracleImpl.refresh(TreeLogger.NULL, lazyResourcesOracle);
} else {
doRefresh();
}
return lazyResourcesOracle;
}
/**
* Gets a reference to the internal rules for this module def.
*/
public synchronized Rules getRules() {
return rules;
}
/**
* Gets a reference to the internal scripts list for this module def.
*/
public Scripts getScripts() {
return scripts;
}
public synchronized String[] getServletPaths() {
return servletClassNamesByPath.keySet().toArray(Empty.STRINGS);
}
/**
* Gets a reference to the internal styles list for this module def.
*/
public Styles getStyles() {
return styles;
}
public boolean isGwtXmlFileStale() {
return lastModified() > moduleDefCreationTime;
}
public long lastModified() {
long lastModified = 0;
for (File xmlFile : gwtXmlFiles) {
if (xmlFile.exists()) {
lastModified = Math.max(lastModified, xmlFile.lastModified());
}
}
return lastModified > 0 ? lastModified : moduleDefCreationTime;
}
/**
* For convenience in hosted mode, servlets can be automatically loaded and
* delegated to via {@link com.google.gwt.dev.shell.GWTShellServlet}. If a
* servlet is already mapped to the specified path, it is replaced.
*
* @param path the url path at which the servlet resides
* @param servletClassName the name of the servlet to publish
*/
public synchronized void mapServlet(String path, String servletClassName) {
servletClassNamesByPath.put(path, servletClassName);
}
public synchronized void refresh() {
needsRefresh = true;
}
/**
* Mainly for testing and decreasing compile times.
*/
public void setCollapseAllProperties(boolean collapse) {
collapseAllProperties = collapse;
}
/**
* Override the module's apparent name. Setting this value to
* null will disable the name override.
*/
public synchronized void setNameOverride(String nameOverride) {
this.nameOverride = nameOverride;
}
/**
* The final method to call when everything is setup. Before calling this
* method, several of the getter methods may not be called. After calling this
* method, the add methods may not be called.
*
* @param logger Logs the activity.
*/
synchronized void normalize(TreeLogger logger) {
Event moduleDefNormalize =
SpeedTracerLogger.start(CompilerEventType.MODULE_DEF, "phase", "normalize");
// Normalize property providers.
//
for (Property current : getProperties()) {
if (current instanceof BindingProperty) {
BindingProperty prop = (BindingProperty) current;
if (collapseAllProperties) {
prop.addCollapsedValues("*");
}
prop.normalizeCollapsedValues();
/*
* Create a default property provider for any properties with more than
* one possible value and no existing provider.
*/
if (prop.getProvider() == null && prop.getConstrainedValue() == null) {
String src = "{";
src += "return __gwt_getMetaProperty(\"";
src += prop.getName();
src += "\"); }";
prop.setProvider(new PropertyProvider(src));
}
}
}
// Create the public path.
TreeLogger branch = Messages.PUBLIC_PATH_LOCATIONS.branch(logger, null);
lazyPublicOracle = new ResourceOracleImpl(branch);
lazyPublicOracle.setPathPrefixes(publicPrefixSet);
// Create the source path.
branch = Messages.SOURCE_PATH_LOCATIONS.branch(logger, null);
lazySourceOracle = new ResourceOracleImpl(branch);
lazySourceOracle.setPathPrefixes(sourcePrefixSet);
needsRefresh = true;
moduleDefNormalize.end();
}
private void checkForSeedTypes(TreeLogger logger,
CompilationState compilationState) throws UnableToCompleteException {
// Sanity check the seed types and don't even start it they're missing.
boolean seedTypesMissing = false;
TypeOracle typeOracle = compilationState.getTypeOracle();
if (typeOracle.findType("java.lang.Object") == null) {
Util.logMissingTypeErrorWithHints(logger, "java.lang.Object");
seedTypesMissing = true;
} else {
TreeLogger branch = logger.branch(TreeLogger.TRACE,
"Finding entry point classes", null);
String[] typeNames = getEntryPointTypeNames();
for (int i = 0; i < typeNames.length; i++) {
String typeName = typeNames[i];
if (typeOracle.findType(typeName) == null) {
Util.logMissingTypeErrorWithHints(branch, typeName);
seedTypesMissing = true;
}
}
}
if (seedTypesMissing) {
throw new UnableToCompleteException();
}
}
private synchronized void doRefresh() {
if (!needsRefresh) {
return;
}
Event moduleDefEvent = SpeedTracerLogger.start(
CompilerEventType.MODULE_DEF, "phase", "refresh", "module", getName());
// Refresh resource oracles.
if (lazyResourcesOracle == null) {
ResourceOracleImpl.refresh(TreeLogger.NULL, lazyPublicOracle,
lazySourceOracle);
} else {
ResourceOracleImpl.refresh(TreeLogger.NULL, lazyPublicOracle,
lazySourceOracle, lazyResourcesOracle);
}
moduleDefEvent.end();
needsRefresh = false;
}
}