This patch updates the ResourceOracleImpl to use a PathPrefix order and prefer PathPrefix order
over Classpath order. It also adds/updates tests to confirm that the above rules are enforced.
Patch by: amitmanjhi
Review by: jat, scottb
git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4520 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ClassPathEntry.java b/dev/core/src/com/google/gwt/dev/resource/impl/ClassPathEntry.java
index aaa46f9..5ada435 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ClassPathEntry.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ClassPathEntry.java
@@ -17,7 +17,7 @@
import com.google.gwt.core.ext.TreeLogger;
-import java.util.Set;
+import java.util.Map;
/**
* A location that acts as a starting point for finding resources
@@ -30,11 +30,12 @@
* begins with a prefix X from the path prefix set and P is allowed by the
* filter associated with X.
*
- * @return a set of zero or more resources; note no guarantees are made
- * regarding the identities of the returned resource objects, and the
- * same object may be returned across multiple calls
+ * @return a map with key as an allowed resource and value as the PathPrefix
+ * that allows the resource; note no guarantees are made regarding the
+ * identities of the returned resource objects, and the same object
+ * may be returned across multiple calls
*/
- public abstract Set<AbstractResource> findApplicableResources(
+ public abstract Map<AbstractResource, PathPrefix> findApplicableResources(
TreeLogger logger, PathPrefixSet pathPrefixSet);
/**
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/DirectoryClassPathEntry.java b/dev/core/src/com/google/gwt/dev/resource/impl/DirectoryClassPathEntry.java
index 7d29ca6..2fd2964 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/DirectoryClassPathEntry.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/DirectoryClassPathEntry.java
@@ -19,8 +19,8 @@
import com.google.gwt.dev.util.msg.Message1String;
import java.io.File;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.IdentityHashMap;
+import java.util.Map;
/**
* TODO(bruce): write me.
@@ -48,9 +48,9 @@
}
@Override
- public Set<AbstractResource> findApplicableResources(TreeLogger logger,
- PathPrefixSet pathPrefixSet) {
- Set<AbstractResource> results = new HashSet<AbstractResource>();
+ public Map<AbstractResource, PathPrefix> findApplicableResources(
+ TreeLogger logger, PathPrefixSet pathPrefixSet) {
+ Map<AbstractResource, PathPrefix> results = new IdentityHashMap<AbstractResource, PathPrefix>();
descendToFindResources(logger, pathPrefixSet, results, dir, "");
return results;
}
@@ -62,14 +62,15 @@
/**
* @param logger logs progress
- * @param resources the accumulating set of resources found
+ * @param resources the accumulating set of resources (each with the
+ * corresponding pathPrefix) found
* @param dir the file or directory to consider
* @param dirPath the abstract path name associated with 'parent', which
* explicitly does not include the classpath entry in its path
*/
private void descendToFindResources(TreeLogger logger,
- PathPrefixSet pathPrefixSet, Set<AbstractResource> resources, File dir,
- String dirPath) {
+ PathPrefixSet pathPrefixSet, Map<AbstractResource, PathPrefix> resources,
+ File dir, String dirPath) {
assert (dir.isDirectory());
// Assert: this directory is included in the path prefix set.
@@ -89,10 +90,11 @@
null);
}
} else {
- if (pathPrefixSet.includesResource(childPath)) {
+ PathPrefix prefix = null;
+ if ((prefix = pathPrefixSet.includesResource(childPath)) != null) {
Messages.INCLUDING_FILE.log(logger, childPath, null);
FileResource r = new FileResource(this, childPath, child);
- resources.add(r);
+ resources.put(r, prefix);
} else {
Messages.EXCLUDING_FILE.log(logger, childPath, null);
}
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/PathPrefixSet.java b/dev/core/src/com/google/gwt/dev/resource/impl/PathPrefixSet.java
index 0e72bf4..c9c5b2d 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/PathPrefixSet.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/PathPrefixSet.java
@@ -15,23 +15,33 @@
*/
package com.google.gwt.dev.resource.impl;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
/**
* Combines the information conveyed about a set of path prefixes to quickly
* answer questions regarding an entire set of path prefixes.
+ *
*/
public class PathPrefixSet {
+ /*
+ * (1) TODO(amitmanjhi): Support multiple PathPrefixes with different filters
+ * but the same "path". This could arise when client code inherits some
+ * library code and defines the same path prefix with a more specific resource
+ * filter.
+ *
+ * (2) TODO(amitmanjhi): Improve the api of the PathPrefixSet so that with one
+ * trie-traversal, it could be found out which resources rooted at a directory
+ * are allowed?
+ */
private static class TrieNode {
- // TODO(bruce): test to see if Map would be faster; I'm on the fence
- private final List<TrieNode> children = new ArrayList<TrieNode>();
+ // TODO(amitmanjhi): Consider the memory-speed tradeoff here
+ private final Map<String, TrieNode> children = new HashMap<String, TrieNode>();
private final String part;
+
private PathPrefix prefix;
public TrieNode(String part) {
@@ -39,19 +49,14 @@
}
public TrieNode addChild(String part) {
- assert (findChild(part) == null);
TrieNode newChild = new TrieNode(part);
- children.add(newChild);
+ TrieNode oldChild = children.put(part, newChild);
+ assert (oldChild == null);
return newChild;
}
public TrieNode findChild(String part) {
- for (TrieNode child : children) {
- if (child.part.equals(part)) {
- return child;
- }
- }
- return null;
+ return children.get(part);
}
public PathPrefix getPathPrefix() {
@@ -80,14 +85,21 @@
sb.append(indent);
sb.append(' ');
sb.append(part);
- for (TrieNode child : children) {
+ for (TrieNode child : children.values()) {
child.toString(sb, indent + " ");
}
}
}
- private int modCount;
- private final Map<String, PathPrefix> prefixes = new HashMap<String, PathPrefix>();
+ /**
+ * The sequence number in which the PathPrefix was added.
+ */
+ private int size = 0;
+
+ /**
+ * Map of pathPrefix => the sequence number when the pathPrefix was added.
+ */
+ private final Map<PathPrefix, Integer> prefixes = new HashMap<PathPrefix, Integer>();
private final TrieNode rootTrieNode = new TrieNode("/");
/**
@@ -98,9 +110,9 @@
* wins)
*/
public boolean add(PathPrefix prefix) {
- ++modCount;
+ ++size;
+ prefixes.put(prefix, size);
String pathPrefix = prefix.getPrefix();
- prefixes.put(pathPrefix, prefix);
/*
* An empty prefix means we have no prefix requirement, but we do attached
@@ -132,8 +144,8 @@
return didAdd;
}
- public int getModCount() {
- return modCount;
+ public int getSize() {
+ return size;
}
/**
@@ -141,19 +153,17 @@
* included. The primary purpose of this method is to allow
* {@link ClassPathEntry} subclasses to avoid descending into directory
* hierarchies that could not possibly contain resources that would be
- * included by {@link #includesResource(String).
+ * included by {@link #includesResource(String)}
*
- * @param dirPath must be a valid abstract directory name or the empty string
- * @return
+ * @param dirPath must be a valid abstract directory name (must not be an
+ * empty string)
+ * @return true if some PathPrefix allows the directory
*/
public boolean includesDirectory(String dirPath) {
assertValidAbstractDirectoryPathName(dirPath);
/*
- * There are five cases:
- *
- * (0) dirPath is the empty string, which is (a) trivially included unless
- * (b) no prefix paths have been specified at all.
+ * There are four cases:
*
* (1) The empty string was specified as a prefix, which causes everything
* to be included.
@@ -171,22 +181,12 @@
* includes it).
*/
- // if ("".equals(dirPath)) {
- // if (rootTrieNode.hasChildren() || rootTrieNode.getPathPrefix() != null) {
- // // Case (0)(a): trivially true.
- // return true;
- // } else {
- // // Case (0)(b): no directories are included.
- // return false;
- // }
- // }
if (rootTrieNode.getPathPrefix() != null) {
// Case (1).
return true;
}
TrieNode parentNode = rootTrieNode;
-
String[] parts = dirPath.split("/");
for (String part : parts) {
assert (!"".equals(part));
@@ -215,10 +215,12 @@
* prefix set and the corresponding filters.
*
* @param resourceAbstractPathName
- * @return <code>true</code> if the resource matches some specified prefix
- * and any associated filters don't exclude it
+ * @return matching <code>PathPrefix</code> if the resource matches some
+ * specified prefix and any associated filters don't exclude it.
+ * Otherwise, returns null. So it returns null if either no prefixes
+ * match or the most specific prefix excludes the resource.
*/
- public boolean includesResource(String resourceAbstractPathName) {
+ public PathPrefix includesResource(String resourceAbstractPathName) {
/*
* Algorithm: dive down the package hierarchy looking for the most specific
* package that applies to this resource. The filter of the most specific
@@ -232,12 +234,8 @@
TrieNode currentNode = rootTrieNode;
PathPrefix mostSpecificPrefix = rootTrieNode.getPathPrefix();
- // TODO(bruce): consider not using split for speed
- String[] parts = resourceAbstractPathName.split("/");
-
// Walk all but the last path part, which is assumed to be a file name.
- for (int i = 0, n = parts.length - 1; i < n; ++i) {
- String part = parts[i];
+ for (String part : resourceAbstractPathName.split("/")) {
assert (!"".equals(part));
TrieNode childNode = currentNode.findChild(part);
if (childNode != null) {
@@ -253,17 +251,35 @@
}
}
- if (mostSpecificPrefix == null) {
- // Didn't match any specified prefix.
- return false;
+ if (mostSpecificPrefix == null
+ || !mostSpecificPrefix.allows(resourceAbstractPathName)) {
+ /*
+ * Didn't match any specified prefix or the filter of the most specific
+ * prefix disallows the resource
+ */
+ return null;
}
- // Test the filter of the most specific prefix we found.
- return mostSpecificPrefix.allows(resourceAbstractPathName);
+ return mostSpecificPrefix;
+ }
+
+ /**
+ * Returns true if the first pathPrefix is inserted into the PathPrefixSet
+ * after the second pathPrefix.
+ *
+ */
+
+ public boolean secondPrefixOverridesFirst(PathPrefix prefix1,
+ PathPrefix prefix2) {
+ int rank1 = prefixes.get(prefix1);
+ assert rank1 > 0;
+ int rank2 = prefixes.get(prefix2);
+ assert rank2 > 0;
+ return rank2 > rank1;
}
public Collection<PathPrefix> values() {
- return Collections.unmodifiableCollection(prefixes.values());
+ return Collections.unmodifiableCollection(prefixes.keySet());
}
private void assertValidAbstractDirectoryPathName(String name) {
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
index 502e634..13c569a 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
@@ -31,6 +31,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -267,19 +268,34 @@
* precedence.
*/
int changeCount = 0;
+ /**
+ * A map from AbstractResources (across all the ClassPathEntry) to their
+ * corresponding PathPrefixes. When old resources are used, an entry is
+ * added to this map from the old resource to the PathPrefix that matches
+ * the resource that the old resource supersedes.
+ */
+ Map<AbstractResource, PathPrefix> globalResourceToPrefixMap = new IdentityHashMap<AbstractResource, PathPrefix>();
for (ClassPathEntry pathRoot : classPath) {
TreeLogger branchForClassPathEntry = Messages.EXAMINING_PATH_ROOT.branch(
refreshBranch, pathRoot.getLocation(), null);
int prevChangeCount = changeCount;
-
- Set<AbstractResource> newResources = pathRoot.findApplicableResources(
+ Map<AbstractResource, PathPrefix> resourceToPrefixMap = pathRoot.findApplicableResources(
branchForClassPathEntry, pathPrefixSet);
- for (AbstractResource newResource : newResources) {
+ globalResourceToPrefixMap.putAll(resourceToPrefixMap);
+ for (AbstractResource newResource : resourceToPrefixMap.keySet()) {
String resourcePath = newResource.getPath();
- // Make sure we don't already have a resource by this name.
- if (newInternalMap.containsKey(resourcePath)) {
+ /*
+ * Check if we have a resource by this name in the newInternalMap and if
+ * the matching pathPrefix overrides the pathPrefix for the previous
+ * resource
+ */
+ AbstractResource existingNewResource = newInternalMap.get(resourcePath);
+ if (existingNewResource != null
+ && !pathPrefixSet.secondPrefixOverridesFirst(
+ globalResourceToPrefixMap.get(existingNewResource),
+ resourceToPrefixMap.get(newResource))) {
Messages.IGNORING_SHADOWED_RESOURCE.log(branchForClassPathEntry,
resourcePath, null);
continue;
@@ -290,12 +306,18 @@
newResource)) {
newInternalMap.put(resourcePath, newResource);
++changeCount;
- } else if (oldResource != null) {
- // Nothing changed, so carry the identity of the old one forward.
+ } else {
+ assert oldResource != null;
+ /*
+ * Nothing changed, so carry the identity of the old one forward. Add
+ * the path-prefix to the global prefix map so that future resources
+ * can be compared.
+ */
newInternalMap.put(resourcePath, oldResource);
+ globalResourceToPrefixMap.put(oldResource,
+ resourceToPrefixMap.get(newResource));
}
}
-
if (changeCount == prevChangeCount) {
Messages.NO_RESOURCES_CHANGED.log(branchForClassPathEntry, null);
}
@@ -316,7 +338,8 @@
}
internalMap = newInternalMap;
- Map<String, Resource> externalMap = rerootResourcePaths(newInternalMap);
+ Map<String, Resource> externalMap = rerootResourcePaths(newInternalMap,
+ globalResourceToPrefixMap);
// Create a constant-time set for resources.
Set<Resource> newResources = new HashSet<Resource>(externalMap.values());
@@ -333,50 +356,53 @@
}
private Map<String, Resource> rerootResourcePaths(
- Map<String, AbstractResource> newInternalMap) {
- Map<String, Resource> externalMap;
+ Map<String, AbstractResource> newInternalMap,
+ Map<AbstractResource, PathPrefix> resourceToPrefixMap) {
+
// Create an external map with rebased path names.
- externalMap = new HashMap<String, Resource>();
+ Map<String, Resource> externalMap = new HashMap<String, Resource>();
for (AbstractResource resource : newInternalMap.values()) {
String path = resource.getPath();
+ assert resourceToPrefixMap.get(resource) != null;
if (externalMap.get(path) instanceof ResourceWrapper) {
- // A rerooted resource blocks any other resource at this path.
- continue;
- }
- int hitCount = 0;
- for (PathPrefix pathPrefix : pathPrefixSet.values()) {
- if (pathPrefix.allows(path)) {
- assert (path.startsWith(pathPrefix.getPrefix()));
- if (pathPrefix.shouldReroot()) {
- String rerootedPath = pathPrefix.getRerootedPath(path);
- if (externalMap.get(rerootedPath) instanceof ResourceWrapper) {
- // A rerooted resource blocks any other resource at this path.
- ++hitCount;
- break;
- }
-
- // Try to reuse the same wrapper.
- Resource exposed = exposedResourceMap.get(rerootedPath);
- if (exposed instanceof ResourceWrapper) {
- ResourceWrapper exposedWrapper = (ResourceWrapper) exposed;
- if (exposedWrapper.resource == resource) {
- externalMap.put(rerootedPath, exposedWrapper);
- ++hitCount;
- break;
- }
- }
- // Just create a new wrapper.
- AbstractResource wrapper = new ResourceWrapper(rerootedPath,
- resource);
- externalMap.put(rerootedPath, wrapper);
- ++hitCount;
- } else {
- externalMap.put(path, resource);
- ++hitCount;
- }
+ // A rerooted resource can block any other resource at this path.
+ ResourceWrapper existingWrapper = (ResourceWrapper) externalMap.get(path);
+ if (!pathPrefixSet.secondPrefixOverridesFirst(
+ resourceToPrefixMap.get(existingWrapper.resource),
+ resourceToPrefixMap.get(resource))) {
+ continue;
}
}
- assert (hitCount > 0);
+
+ PathPrefix pathPrefix = resourceToPrefixMap.get(resource);
+ assert pathPrefix != null;
+ if (pathPrefix.shouldReroot()) {
+ String rerootedPath = pathPrefix.getRerootedPath(path);
+ if (externalMap.get(rerootedPath) instanceof ResourceWrapper) {
+ ResourceWrapper existingWrapper = (ResourceWrapper) externalMap.get(rerootedPath);
+ if (!pathPrefixSet.secondPrefixOverridesFirst(
+ resourceToPrefixMap.get(existingWrapper.resource),
+ resourceToPrefixMap.get(resource))) {
+ // A rerooted resource blocks any other resource at this path.
+ continue;
+ }
+ }
+
+ // Try to reuse the same wrapper.
+ Resource exposed = exposedResourceMap.get(rerootedPath);
+ if (exposed instanceof ResourceWrapper) {
+ ResourceWrapper exposedWrapper = (ResourceWrapper) exposed;
+ if (exposedWrapper.resource == resource) {
+ externalMap.put(rerootedPath, exposedWrapper);
+ continue;
+ }
+ }
+ // Just create a new wrapper.
+ AbstractResource wrapper = new ResourceWrapper(rerootedPath, resource);
+ externalMap.put(rerootedPath, wrapper);
+ } else {
+ externalMap.put(path, resource);
+ }
}
return externalMap;
}
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
index 6076260..f7a0420 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
@@ -21,6 +21,8 @@
import java.io.File;
import java.util.Enumeration;
import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -51,9 +53,10 @@
}
private Set<ZipFileResource> allZipFileResources;
- private Set<AbstractResource> cachedAnswers;
+ private Map<AbstractResource, PathPrefix> cachedAnswers;
private String cachedLocation;
private PathPrefixSet lastPrefixSet;
+ private int lastPrefixSetSize;
private final ZipFile zipFile;
public ZipFileClassPathEntry(ZipFile zipFile) {
@@ -64,18 +67,19 @@
* Indexes the zip file on-demand, and only once over the life of the process.
*/
@Override
- public Set<AbstractResource> findApplicableResources(TreeLogger logger,
- PathPrefixSet pathPrefixSet) {
+ public Map<AbstractResource, PathPrefix> findApplicableResources(
+ TreeLogger logger, PathPrefixSet pathPrefixSet) {
// Never re-index.
if (allZipFileResources == null) {
allZipFileResources = buildIndex(logger);
}
if (cachedAnswers == null || lastPrefixSet != pathPrefixSet
- || lastPrefixSet.getModCount() != pathPrefixSet.getModCount()) {
+ || lastPrefixSetSize != pathPrefixSet.getSize()) {
cachedAnswers = computeApplicableResources(logger, pathPrefixSet);
+ lastPrefixSet = pathPrefixSet;
+ lastPrefixSetSize = pathPrefixSet.getSize();
}
-
return cachedAnswers;
}
@@ -113,17 +117,18 @@
return results;
}
- private Set<AbstractResource> computeApplicableResources(TreeLogger logger,
- PathPrefixSet pathPrefixSet) {
+ private Map<AbstractResource, PathPrefix> computeApplicableResources(
+ TreeLogger logger, PathPrefixSet pathPrefixSet) {
logger = Messages.FINDING_INCLUDED_RESOURCES.branch(logger,
zipFile.getName(), null);
- Set<AbstractResource> results = new HashSet<AbstractResource>();
+ Map<AbstractResource, PathPrefix> results = new IdentityHashMap<AbstractResource, PathPrefix>();
for (ZipFileResource r : allZipFileResources) {
String path = r.getPath();
- if (pathPrefixSet.includesResource(path)) {
+ PathPrefix prefix = null;
+ if ((prefix = pathPrefixSet.includesResource(path)) != null) {
Messages.INCLUDING_RESOURCE.log(logger, path, null);
- results.add(r);
+ results.put(r, prefix);
} else {
Messages.EXCLUDING_RESOURCE.log(logger, path, null);
}
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/AbstractResourceOrientedTestBase.java b/dev/core/test/com/google/gwt/dev/resource/impl/AbstractResourceOrientedTestBase.java
index 489e571..29c9feb 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/AbstractResourceOrientedTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/AbstractResourceOrientedTestBase.java
@@ -25,7 +25,8 @@
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
-import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Map;
import java.util.Set;
import java.util.jar.JarFile;
@@ -67,14 +68,14 @@
}
@Override
- public Set<AbstractResource> findApplicableResources(TreeLogger logger,
- PathPrefixSet pathPrefixSet) {
- Set<AbstractResource> results = new HashSet<AbstractResource>();
- Set<AbstractResource> rs = cpe.findApplicableResources(logger,
- pathPrefixSet);
- for (AbstractResource r : rs) {
+ public Map<AbstractResource, PathPrefix> findApplicableResources(
+ TreeLogger logger, PathPrefixSet pathPrefixSet) {
+ Map<AbstractResource, PathPrefix> results = new IdentityHashMap<AbstractResource, PathPrefix>();
+ Map<AbstractResource, PathPrefix> rs = cpe.findApplicableResources(
+ logger, pathPrefixSet);
+ for (AbstractResource r : rs.keySet()) {
if (r.getPath().indexOf(".svn/") < 0) {
- results.add(r);
+ results.put(r, rs.get(r));
}
}
return results;
@@ -114,6 +115,7 @@
addResource("com/google/gwt/i18n/rebind/LocalizableGenerator.java");
addResource("org/example/bar/client/BarClient2.txt");
addResource("org/example/bar/client/BarClient3.txt");
+ addResource("org/example/foo/client/BarClient1.txt");
}
}
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/ClassPathEntryTest.java b/dev/core/test/com/google/gwt/dev/resource/impl/ClassPathEntryTest.java
index 3454176..5bfddad 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/ClassPathEntryTest.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/ClassPathEntryTest.java
@@ -81,7 +81,7 @@
{
// Examine cpe1.
- Set<AbstractResource> r = cpe1.findApplicableResources(logger, pps);
+ Set<AbstractResource> r = cpe1.findApplicableResources(logger, pps).keySet();
assertEquals(3, r.size());
assertPathIncluded(r, "com/google/gwt/user/client/Command.java");
@@ -91,7 +91,7 @@
{
// Examine cpe2.
- Set<AbstractResource> r = cpe2.findApplicableResources(logger, pps);
+ Set<AbstractResource> r = cpe2.findApplicableResources(logger, pps).keySet();
assertEquals(1, r.size());
assertPathIncluded(r, "com/google/gwt/i18n/client/Messages.java");
@@ -106,7 +106,7 @@
PathPrefixSet pps = new PathPrefixSet();
pps.add(new PathPrefix("", null));
- Set<AbstractResource> r = cpe1.findApplicableResources(logger, pps);
+ Set<AbstractResource> r = cpe1.findApplicableResources(logger, pps).keySet();
assertEquals(9, r.size());
assertPathIncluded(r, "com/google/gwt/user/User.gwt.xml");
@@ -127,15 +127,16 @@
PathPrefixSet pps = new PathPrefixSet();
pps.add(new PathPrefix("", null));
- Set<AbstractResource> r = cpe2.findApplicableResources(logger, pps);
+ Set<AbstractResource> r = cpe2.findApplicableResources(logger, pps).keySet();
- assertEquals(5, r.size());
+ assertEquals(6, r.size());
assertPathIncluded(r, "com/google/gwt/i18n/I18N.gwt.xml");
assertPathIncluded(r, "com/google/gwt/i18n/client/Messages.java");
assertPathIncluded(r,
"com/google/gwt/i18n/rebind/LocalizableGenerator.java");
assertPathIncluded(r, "org/example/bar/client/BarClient2.txt");
assertPathIncluded(r, "org/example/bar/client/BarClient3.txt");
+ assertPathIncluded(r, "org/example/foo/client/BarClient1.txt");
}
private void testPathPrefixSetChanges(ClassPathEntry cpe1, ClassPathEntry cpe2) {
@@ -148,7 +149,7 @@
pps.add(new PathPrefix("com/google/gwt/i18n/", null));
// Examine cpe1 in the absence of the filter.
- Set<AbstractResource> r1 = cpe1.findApplicableResources(logger, pps);
+ Set<AbstractResource> r1 = cpe1.findApplicableResources(logger, pps).keySet();
assertEquals(4, r1.size());
assertPathIncluded(r1, "com/google/gwt/user/User.gwt.xml");
@@ -157,7 +158,7 @@
assertPathIncluded(r1, "com/google/gwt/user/client/ui/Widget.java");
// Examine cpe2 in the absence of the filter.
- Set<AbstractResource> r2 = cpe2.findApplicableResources(logger, pps);
+ Set<AbstractResource> r2 = cpe2.findApplicableResources(logger, pps).keySet();
assertEquals(3, r2.size());
assertPathIncluded(r2, "com/google/gwt/i18n/I18N.gwt.xml");
@@ -179,7 +180,7 @@
pps.add(new PathPrefix("com/google/gwt/i18n/", excludeXmlFiles));
// Examine cpe1 in the presence of the filter.
- Set<AbstractResource> r1 = cpe1.findApplicableResources(logger, pps);
+ Set<AbstractResource> r1 = cpe1.findApplicableResources(logger, pps).keySet();
assertEquals(3, r1.size());
assertPathNotIncluded(r1, "com/google/gwt/user/User.gwt.xml");
@@ -188,7 +189,7 @@
assertPathIncluded(r1, "com/google/gwt/user/client/ui/Widget.java");
// Examine cpe2 in the presence of the filter.
- Set<AbstractResource> r2 = cpe2.findApplicableResources(logger, pps);
+ Set<AbstractResource> r2 = cpe2.findApplicableResources(logger, pps).keySet();
assertEquals(2, r2.size());
assertPathNotIncluded(r1, "com/google/gwt/user/User.gwt.xml");
@@ -211,12 +212,12 @@
}));
// Examine cpe1 in the presence of the filter.
- Set<AbstractResource> r1 = cpe1.findApplicableResources(logger, pps);
+ Set<AbstractResource> r1 = cpe1.findApplicableResources(logger, pps).keySet();
assertEquals(0, r1.size());
// Examine cpe2 in the presence of the filter.
- Set<AbstractResource> r2 = cpe2.findApplicableResources(logger, pps);
+ Set<AbstractResource> r2 = cpe2.findApplicableResources(logger, pps).keySet();
assertEquals(0, r2.size());
}
@@ -238,7 +239,7 @@
{
// Examine cpe1.
- Set<AbstractResource> r = cpe1.findApplicableResources(logger, pps);
+ Set<AbstractResource> r = cpe1.findApplicableResources(logger, pps).keySet();
assertEquals(3, r.size());
// User.gwt.xml would be included but for the filter.
@@ -249,7 +250,7 @@
{
// Examine cpe2.
- Set<AbstractResource> r = cpe2.findApplicableResources(logger, pps);
+ Set<AbstractResource> r = cpe2.findApplicableResources(logger, pps).keySet();
assertEquals(2, r.size());
// I18N.gwt.xml would be included but for the filter.
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/MockClassPathEntry.java b/dev/core/test/com/google/gwt/dev/resource/impl/MockClassPathEntry.java
index 913b071..254c0f9 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/MockClassPathEntry.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/MockClassPathEntry.java
@@ -21,9 +21,8 @@
import junit.framework.Assert;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.Map;
-import java.util.Set;
public class MockClassPathEntry extends ClassPathEntry {
@@ -46,14 +45,15 @@
}
@Override
- public Set<AbstractResource> findApplicableResources(TreeLogger logger,
- PathPrefixSet pathPrefixes) {
+ public Map<AbstractResource, PathPrefix> findApplicableResources(
+ TreeLogger logger, PathPrefixSet pathPrefixes) {
// Only include resources that have the prefix and pass its filter.
- HashSet<AbstractResource> results = new HashSet<AbstractResource>();
+ Map<AbstractResource, PathPrefix> results = new IdentityHashMap<AbstractResource, PathPrefix>();
for (Map.Entry<String, MockAbstractResource> entry : resourceMap.entrySet()) {
String path = entry.getKey();
- if (pathPrefixes.includesResource(path)) {
- results.add(entry.getValue());
+ PathPrefix prefix = null;
+ if ((prefix = pathPrefixes.includesResource(path)) != null) {
+ results.put(entry.getValue(), prefix);
}
}
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/PathPrefixSetTest.java b/dev/core/test/com/google/gwt/dev/resource/impl/PathPrefixSetTest.java
index e9d581c..8c73c99 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/PathPrefixSetTest.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/PathPrefixSetTest.java
@@ -24,154 +24,181 @@
public void testEmptyPrefixSet() {
PathPrefixSet pps = new PathPrefixSet();
- assertFalse(pps.includesResource("com/google/gwt/user/client/Command.java"));
+ assertNull(pps.includesResource("com/google/gwt/user/client/Command.java"));
}
- public void testNonOverlappingPrefixes() {
- {
- /*
- * Test with null filters to ensure nothing gets filtered out.
- */
- PathPrefixSet pps = new PathPrefixSet();
- pps.add(new PathPrefix("com/google/gwt/user/client/", null));
- pps.add(new PathPrefix("com/google/gwt/i18n/client/", null));
- pps.add(new PathPrefix("com/google/gwt/dom/client/", null));
+ public void testNonOverlappingPrefixesEmptyFilter() {
+ /*
+ * Test with null filters to ensure nothing gets filtered out.
+ */
+ PathPrefixSet pps = new PathPrefixSet();
+ PathPrefix pp1 = new PathPrefix("com/google/gwt/user/client/", null);
+ PathPrefix pp2 = new PathPrefix("com/google/gwt/i18n/client/", null);
+ PathPrefix pp3 = new PathPrefix("com/google/gwt/dom/client/", null);
+ pps.add(pp1);
+ pps.add(pp2);
+ pps.add(pp3);
- assertTrue(pps.includesDirectory("com/"));
- assertTrue(pps.includesDirectory("com/google/"));
- assertTrue(pps.includesDirectory("com/google/gwt/"));
- assertTrue(pps.includesDirectory("com/google/gwt/user/"));
- assertTrue(pps.includesDirectory("com/google/gwt/user/client/"));
- assertTrue(pps.includesDirectory("com/google/gwt/user/client/ui/"));
+ assertTrue(pps.includesDirectory("com/"));
+ assertTrue(pps.includesDirectory("com/google/"));
+ assertTrue(pps.includesDirectory("com/google/gwt/"));
+ assertTrue(pps.includesDirectory("com/google/gwt/user/"));
+ assertTrue(pps.includesDirectory("com/google/gwt/user/client/"));
+ assertTrue(pps.includesDirectory("com/google/gwt/user/client/ui/"));
- assertFalse(pps.includesDirectory("org/"));
- assertFalse(pps.includesDirectory("org/example/"));
- assertFalse(pps.includesDirectory("com/google/gwt/user/server/"));
- assertFalse(pps.includesDirectory("com/google/gwt/xml/client/"));
+ assertFalse(pps.includesDirectory("org/"));
+ assertFalse(pps.includesDirectory("org/example/"));
+ assertFalse(pps.includesDirectory("com/google/gwt/user/server/"));
+ assertFalse(pps.includesDirectory("com/google/gwt/xml/client/"));
- assertTrue(pps.includesResource("com/google/gwt/user/client/Command.java"));
- assertTrue(pps.includesResource("com/google/gwt/user/client/Timer.java"));
- assertTrue(pps.includesResource("com/google/gwt/i18n/client/Messages.java"));
- assertTrue(pps.includesResource("com/google/gwt/dom/client/DivElement.java"));
+ assertEquals(pp1,
+ pps.includesResource("com/google/gwt/user/client/Command.java"));
+ assertEquals(pp1,
+ pps.includesResource("com/google/gwt/user/client/Timer.java"));
+ assertEquals(pp2,
+ pps.includesResource("com/google/gwt/i18n/client/Messages.java"));
+ assertEquals(pp3,
+ pps.includesResource("com/google/gwt/dom/client/DivElement.java"));
- assertFalse(pps.includesResource("com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java"));
- assertFalse(pps.includesResource("com/google/gwt/sample/hello/client/Hello.java"));
- assertFalse(pps.includesResource("com/google/gwt/user/public/clear.cache.gif"));
- }
-
- {
- /*
- * Test with a real filter to ensure it does have an effect.
- */
- PathPrefixSet pps = new PathPrefixSet();
- ResourceFilter allowsGifs = new ResourceFilter() {
- public boolean allows(String path) {
- return path.toLowerCase().endsWith(".gif");
- }
- };
-
- pps.add(new PathPrefix("com/google/gwt/user/public/", allowsGifs));
- pps.add(new PathPrefix("com/google/gwt/sample/mail/public/", allowsGifs));
-
- // Correct prefix, and filter should allow .
- assertTrue(pps.includesResource("com/google/gwt/user/public/clear.cache.gif"));
- assertTrue(pps.includesResource("com/google/gwt/sample/mail/public/inboxIcon.gif"));
-
- // Correct prefix, but filter should exclude.
- assertFalse(pps.includesResource("com/google/gwt/user/public/README.txt"));
- assertFalse(pps.includesResource("com/google/gwt/sample/mail/public/README.txt"));
-
- // Wrong prefix, and filter would have excluded.
- assertFalse(pps.includesResource("com/google/gwt/user/client/Command.java"));
- assertFalse(pps.includesResource("com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java"));
-
- // Wrong prefix, but filter would have allowed it.
- assertFalse(pps.includesResource("com/google/gwt/i18n/public/flags.gif"));
- }
+ assertNull(pps.includesResource("com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java"));
+ assertNull(pps.includesResource("com/google/gwt/sample/hello/client/Hello.java"));
+ assertNull(pps.includesResource("com/google/gwt/user/public/clear.cache.gif"));
}
- public void testOverlappingPrefixes() {
- {
- /*
- * Without a filter.
- */
- PathPrefixSet pps = new PathPrefixSet();
- pps.add(new PathPrefix("", null));
- pps.add(new PathPrefix("a/", null));
- pps.add(new PathPrefix("a/b/", null));
- pps.add(new PathPrefix("a/b/c/", null));
+ public void testNonOverlappingPrefixesNonEmptyFilter() {
+ /*
+ * Test with a real filter to ensure it does have an effect.
+ */
+ PathPrefixSet pps = new PathPrefixSet();
+ ResourceFilter allowsGifs = new ResourceFilter() {
+ public boolean allows(String path) {
+ return path.toLowerCase().endsWith(".gif");
+ }
+ };
- assertTrue(pps.includesResource("W.java"));
- assertTrue(pps.includesResource("a/X.java"));
- assertTrue(pps.includesResource("a/b/Y.java"));
- assertTrue(pps.includesResource("a/b/c/Z.java"));
- assertTrue(pps.includesResource("a/b/c/d/V.java"));
- }
+ PathPrefix pp1 = new PathPrefix("com/google/gwt/user/public/", allowsGifs);
+ PathPrefix pp2 = new PathPrefix("com/google/gwt/sample/mail/public/",
+ allowsGifs);
+ pps.add(pp1);
+ pps.add(pp2);
- {
- /*
- * Ensure the right filter applies.
- */
- PathPrefixSet pps = new PathPrefixSet();
- pps.add(new PathPrefix("", null));
- pps.add(new PathPrefix("a/", null));
- pps.add(new PathPrefix("a/b/", new ResourceFilter() {
- public boolean allows(String path) {
- // Disallow anything ending with "FILTERMEOUT".
- return !path.endsWith("FILTERMEOUT");
- }
- }));
- pps.add(new PathPrefix("a/b/c/", null));
+ // Correct prefix, and filter should allow .
+ assertEquals(pp1,
+ pps.includesResource("com/google/gwt/user/public/clear.cache.gif"));
+ assertEquals(pp2,
+ pps.includesResource("com/google/gwt/sample/mail/public/inboxIcon.gif"));
- assertTrue(pps.includesResource("W.java"));
- assertTrue(pps.includesResource("a/X.java"));
- assertTrue(pps.includesResource("a/b/Y.java"));
- // This should be gone, since it is found in b.
- assertFalse(pps.includesResource("a/b/FILTERMEOUT"));
- /*
- * This should not be gone, because it is using c's (null) filter instead
- * of b's. The logic here is that the prefix including c is more specific
- * and seemed to want c's resources to be included.
- */
- assertTrue(pps.includesResource("a/b/c/DONT_FILTERMEOUT"));
- assertTrue(pps.includesResource("a/b/c/Z.java"));
- assertTrue(pps.includesResource("a/b/c/d/V.java"));
- }
+ // Correct prefix, but filter should exclude.
+ assertNull(pps.includesResource("com/google/gwt/user/public/README.txt"));
+ assertNull(pps.includesResource("com/google/gwt/sample/mail/public/README.txt"));
+
+ // Wrong prefix, and filter would have excluded.
+ assertNull(pps.includesResource("com/google/gwt/user/client/Command.java"));
+ assertNull(pps.includesResource("com/google/gwt/user/rebind/rpc/ServiceInterfaceProxyGenerator.java"));
+
+ // Wrong prefix, but filter would have allowed it.
+ assertNull(pps.includesResource("com/google/gwt/i18n/public/flags.gif"));
+ }
+
+ public void testOverlappingPrefixesEmptyFilter() {
+ /*
+ * Without a filter.
+ */
+ PathPrefixSet pps = new PathPrefixSet();
+ PathPrefix pp1 = new PathPrefix("a/b/", null);
+ PathPrefix pp2 = new PathPrefix("a/", null);
+ PathPrefix pp3 = new PathPrefix("", null);
+ PathPrefix pp4 = new PathPrefix("a/b/c/", null);
+ PathPrefix pp5 = new PathPrefix("a/", null);
+ pps.add(pp1);
+ pps.add(pp2);
+ pps.add(pp3);
+ pps.add(pp4);
+ // pp5 now overrides pp2
+ pps.add(pp5);
+
+ assertEquals(pp3, pps.includesResource("W.java"));
+ assertEquals(pp5, pps.includesResource("a/X.java"));
+ assertEquals(pp1, pps.includesResource("a/b/Y.java"));
+ assertEquals(pp4, pps.includesResource("a/b/c/Z.java"));
+ assertEquals(pp4, pps.includesResource("a/b/c/d/V.java"));
+ }
+
+ public void testOverlappingPrefixesNonEmptyFilter() {
+ /*
+ * Ensure the right filter applies.
+ */
+ PathPrefixSet pps = new PathPrefixSet();
+ PathPrefix pp1 = new PathPrefix("", null);
+ PathPrefix pp2 = new PathPrefix("a/", null);
+ PathPrefix pp3 = new PathPrefix("a/b/", new ResourceFilter() {
+ public boolean allows(String path) {
+ // Disallow anything ending with "FILTERMEOUT".
+ return !path.endsWith("FILTERMEOUT");
+ }
+ });
+ PathPrefix pp4 = new PathPrefix("a/b/c/", null);
+ PathPrefix pp5 = new PathPrefix("a/", new ResourceFilter() {
+ public boolean allows(String path) {
+ return !path.endsWith("X.java");
+ }
+ });
+ pps.add(pp1);
+ pps.add(pp2);
+ pps.add(pp3);
+ pps.add(pp4);
+ pps.add(pp5);
+
+ assertEquals(pp1, pps.includesResource("W.java"));
+
+ // see TODO in the implementation note for PathPrefixSet.java
+ // assertEquals(pp2, pps.includesResource("a/X.java"));
+ assertEquals(pp5, pps.includesResource("a/Y.java"));
+ assertEquals(pp3, pps.includesResource("a/b/Y.java"));
+ // This should be gone, since it is found in b.
+ assertNull(pps.includesResource("a/b/FILTERMEOUT"));
+ /*
+ * This should not be gone, because it is using c's (null) filter instead of
+ * b's. The logic here is that the prefix including c is more specific and
+ * seemed to want c's resources to be included.
+ */
+ assertEquals(pp4, pps.includesResource("a/b/c/DONT_FILTERMEOUT"));
+ assertEquals(pp4, pps.includesResource("a/b/c/Z.java"));
+ assertEquals(pp4, pps.includesResource("a/b/c/d/V.java"));
}
/**
- * In essense, this tests support for the default package in Java.
+ * In essence, this tests support for the default package in Java.
*/
- public void testZeroLengthPrefix() {
- {
- /*
- * Without a filter.
- */
- PathPrefixSet pps = new PathPrefixSet();
- pps.add(new PathPrefix("", null));
+ public void testZeroLengthPrefixEmptyFilter() {
+ /*
+ * Without a filter.
+ */
+ PathPrefixSet pps = new PathPrefixSet();
+ PathPrefix pp1 = new PathPrefix("", null);
+ pps.add(pp1);
- assertTrue(pps.includesResource("W.java"));
- assertTrue(pps.includesResource("a/X.java"));
- assertTrue(pps.includesResource("a/b/Y.java"));
- assertTrue(pps.includesResource("a/b/c/Z.java"));
- }
+ assertEquals(pp1, pps.includesResource("W.java"));
+ assertEquals(pp1, pps.includesResource("a/X.java"));
+ assertEquals(pp1, pps.includesResource("a/b/Y.java"));
+ assertEquals(pp1, pps.includesResource("a/b/c/Z.java"));
+ }
- {
- /*
- * With a filter.
- */
- PathPrefixSet pps = new PathPrefixSet();
- pps.add(new PathPrefix("", new ResourceFilter() {
- public boolean allows(String path) {
- return path.endsWith("Y.java");
- }
- }));
+ public void testZeroLengthPrefixNonEmptyFilter() {
+ /*
+ * With a filter.
+ */
+ PathPrefixSet pps = new PathPrefixSet();
+ PathPrefix pp1 = new PathPrefix("", new ResourceFilter() {
+ public boolean allows(String path) {
+ return path.endsWith("Y.java");
+ }
+ });
+ pps.add(pp1);
- assertFalse(pps.includesResource("W.java"));
- assertFalse(pps.includesResource("a/X.java"));
- assertTrue(pps.includesResource("a/b/Y.java"));
- assertFalse(pps.includesResource("a/b/c/Z.java"));
-
- }
+ assertNull(pps.includesResource("W.java"));
+ assertNull(pps.includesResource("a/X.java"));
+ assertEquals(pp1, pps.includesResource("a/b/Y.java"));
+ assertNull(pps.includesResource("a/b/c/Z.java"));
}
}
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java b/dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java
index 46e166d..a4b1912 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java
@@ -164,6 +164,62 @@
}
/**
+ * Test that ResourceOracleImpl prefers the order of path prefixes over
+ * ClassPathEntries.
+ * <p>
+ * cpe1 contains org/example/bar/client/BarClient1.txt and cpe2 contains
+ * org/example/foo/client/BarClient1.txt
+ *
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+ public void testPathPrefixOrderPreferredOverClasspath() throws IOException,
+ URISyntaxException {
+ TreeLogger logger = createTestTreeLogger();
+ ClassPathEntry cpe1jar = getClassPathEntry1AsJar();
+ ClassPathEntry cpe2jar = getClassPathEntry2AsJar();
+
+ ClassPathEntry[] cp12 = new ClassPathEntry[] {cpe1jar, cpe2jar};
+ ClassPathEntry[] cp21 = new ClassPathEntry[] {cpe2jar, cpe1jar};
+
+ String barKeyNormal = "org/example/bar/client/BarClient1.txt";
+ String keyReroot = "/BarClient1.txt";
+ String fooKeyNormal = "org/example/foo/client/BarClient1.txt";
+
+ PathPrefix pathPrefix1Reroot = new PathPrefix("org/example/bar/client",
+ null, true);
+ PathPrefix pathPrefix2Reroot = new PathPrefix("org/example/foo/client",
+ null, true);
+
+ PathPrefixSet pps12Reroot = new PathPrefixSet();
+ pps12Reroot.add(pathPrefix1Reroot);
+ pps12Reroot.add(pathPrefix2Reroot);
+
+ PathPrefixSet pps21Reroot = new PathPrefixSet();
+ pps21Reroot.add(pathPrefix2Reroot);
+ pps21Reroot.add(pathPrefix1Reroot);
+
+ /*
+ * the keyReroot resource in cpe2 wins because pathPrefix2Reroot comes
+ * later.
+ */
+ testPathPrefixOrderPreferredOverClasspath(logger, keyReroot, cp12,
+ pps12Reroot, 1);
+ // order of specifying classpath is reversed, it still matches cpe2
+ testPathPrefixOrderPreferredOverClasspath(logger, keyReroot, cp21,
+ pps12Reroot, 0);
+ /*
+ * the keyReroot resource in cpe2 wins because pathPrefix2Reroot comes
+ * later.
+ */
+ testPathPrefixOrderPreferredOverClasspath(logger, keyReroot, cp12,
+ pps21Reroot, 0);
+ // order of specifying classpath is reversed, it still matches cpe1
+ testPathPrefixOrderPreferredOverClasspath(logger, keyReroot, cp21,
+ pps21Reroot, 1);
+ }
+
+ /**
* Tests the actual reading of resources.
*
* @throws URISyntaxException
@@ -273,11 +329,15 @@
oracle.setPathPrefixes(pps);
return oracle;
}
-
+
private ResourceOracleSnapshot refreshAndSnapshot(TreeLogger logger,
ResourceOracleImpl oracle) {
oracle.refresh(logger);
- return new ResourceOracleSnapshot(oracle);
+ ResourceOracleSnapshot snapshot1 = new ResourceOracleSnapshot(oracle);
+ oracle.refresh(logger);
+ ResourceOracleSnapshot snapshot2 = new ResourceOracleSnapshot(oracle);
+ snapshot1.assertSameCollections(snapshot2);
+ return snapshot1;
}
private void testClassPathOrderIsHonored(TreeLogger logger,
@@ -290,13 +350,22 @@
s.assertPathIncluded(resourceKey, classPath[0]);
}
+ private void testPathPrefixOrderPreferredOverClasspath(TreeLogger logger,
+ String resourceKey, ClassPathEntry[] classPath, PathPrefixSet pps,
+ int index) {
+ ResourceOracleImpl oracle = new ResourceOracleImpl(Arrays.asList(classPath));
+ oracle.setPathPrefixes(pps);
+ ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
+ s.assertPathIncluded(resourceKey, classPath[index]);
+ }
+
private void testReadingResource(ClassPathEntry cpe1, ClassPathEntry cpe2)
throws IOException {
TreeLogger logger = createTestTreeLogger();
ResourceOracleImpl oracle = createResourceOracle(cpe1, cpe2);
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
- s.assertCollectionsConsistent(9);
+ s.assertCollectionsConsistent(10);
s.assertPathIncluded("com/google/gwt/user/client/Command.java", cpe1);
s.assertPathIncluded("com/google/gwt/i18n/client/Messages.java", cpe2);
@@ -354,7 +423,7 @@
* assumptions about the contents of each classpath entry.
*/
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
- s.assertCollectionsConsistent(9);
+ s.assertCollectionsConsistent(10);
s.assertPathIncluded("com/google/gwt/user/client/Command.java");
s.assertPathIncluded("com/google/gwt/user/client/Timer.java");
s.assertPathIncluded("com/google/gwt/user/client/ui/Widget.java");
@@ -377,7 +446,7 @@
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
- after.assertCollectionsConsistent(9);
+ after.assertCollectionsConsistent(10);
after.assertSameCollections(before);
}
@@ -390,7 +459,7 @@
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
- after.assertCollectionsConsistent(10);
+ after.assertCollectionsConsistent(11);
after.assertNotSameCollections(before);
after.assertPathIncluded("com/google/gwt/i18n/client/Constants.java");
}
@@ -417,7 +486,7 @@
* assumptions about the contents of each classpath entry.
*/
ResourceOracleSnapshot s = refreshAndSnapshot(logger, oracle);
- s.assertCollectionsConsistent(10);
+ s.assertCollectionsConsistent(11);
s.assertPathIncluded("com/google/gwt/user/client/Command.java");
s.assertPathIncluded("com/google/gwt/user/client/Timer.java");
s.assertPathIncluded("com/google/gwt/user/client/ui/Widget.java");
@@ -440,7 +509,7 @@
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
- after.assertCollectionsConsistent(10);
+ after.assertCollectionsConsistent(11);
after.assertSameCollections(before);
}
@@ -455,7 +524,7 @@
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
ResourceOracleSnapshot after = refreshAndSnapshot(logger, oracle);
- after.assertCollectionsConsistent(10);
+ after.assertCollectionsConsistent(11);
after.assertNotSameCollections(before);
after.assertPathIncluded("com/google/gwt/user/client/Window.java");
after.assertPathNotIncluded("com/google/gwt/i18n/client/Constants.java");
@@ -497,7 +566,7 @@
* isn't observed.
*/
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
- before.assertCollectionsConsistent(9);
+ before.assertCollectionsConsistent(10);
cpe3.updateResource("com/google/gwt/user/client/Timer.java");
@@ -511,7 +580,7 @@
* is observed.
*/
ResourceOracleSnapshot before = new ResourceOracleSnapshot(oracle);
- before.assertCollectionsConsistent(9);
+ before.assertCollectionsConsistent(10);
cpe0.updateResource("com/google/gwt/user/client/Command.java");
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe1.jar b/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe1.jar
index 5045c12..c5127c9 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe1.jar
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe1.jar
Binary files differ
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe2.jar b/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe2.jar
index 08761bb..2e6663b 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe2.jar
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe2.jar
Binary files differ
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe2/org/example/foo/client/BarClient1.txt b/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe2/org/example/foo/client/BarClient1.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/testdata/cpe2/org/example/foo/client/BarClient1.txt
@@ -0,0 +1 @@
+