FileResource and ClassPathEntry cleanup.
- Changes interning of FileResource to be thread-safe.
- Renames FileResource.create to FileResource.of as it
doesn't always create.
- Drops the test-only needed getClassPathEntry from all
Resource types.
- Removes unused findApplicableResources overload from all
ClassPathEntry types.
Change-Id: I0d588dde8ae9220221c5f2255d01aa1feaba2c7b
Review-Link: https://gwt-review.googlesource.com/#/c/10830/
diff --git a/dev/core/src/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompiler.java
index 25f560b..561f759 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompiler.java
@@ -277,7 +277,7 @@
String resourcePath = entry.getKey();
File resourceFile = entry.getValue();
compilerContext.getLibraryWriter()
- .addBuildResource(FileResource.create(null, resourcePath, resourceFile));
+ .addBuildResource(FileResource.of(resourcePath, resourceFile));
}
}
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/AbstractResource.java b/dev/core/src/com/google/gwt/dev/resource/impl/AbstractResource.java
index f0f9308..fe6a1e8 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/AbstractResource.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/AbstractResource.java
@@ -22,11 +22,6 @@
*/
public abstract class AbstractResource extends Resource {
- /**
- * Accesses the path root under which this resource was found. Only available within this package.
- */
- public abstract ClassPathEntry getClassPathEntry();
-
@Override
public boolean wasRerooted() {
return false;
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 c7655e9..83edd86 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,8 +17,6 @@
import com.google.gwt.core.ext.TreeLogger;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
/**
@@ -41,22 +39,6 @@
}
/**
- * Finds applicable resources for a list of pathPrefixSets, returning a
- * distinct answer for each set.
- *
- * @see #findApplicableResources(TreeLogger, PathPrefixSet)
- */
- public List<Map<AbstractResource, ResourceResolution>> findApplicableResources(
- TreeLogger logger, List<PathPrefixSet> pathPrefixSets) {
- List<Map<AbstractResource, ResourceResolution>> results = new ArrayList<
- Map<AbstractResource, ResourceResolution>>(pathPrefixSets.size());
- for (PathPrefixSet pathPrefixSet : pathPrefixSets) {
- results.add(findApplicableResources(logger, pathPrefixSet));
- }
- return results;
- }
-
- /**
* Finds every resource at abstract path P within this classpath such that P
* begins with a prefix X from the path prefix set and P is allowed by the
* filter associated with X.
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 1bc2a34..e496f21 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
@@ -24,7 +24,6 @@
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.List;
@@ -81,18 +80,6 @@
}
@Override
- public List<Map<AbstractResource, ResourceResolution>> findApplicableResources(
- TreeLogger logger, List<PathPrefixSet> pathPrefixSets) {
- List<Map<AbstractResource, ResourceResolution>> results =
- new ArrayList<Map<AbstractResource, ResourceResolution>>(pathPrefixSets.size());
- for (PathPrefixSet pathPrefixSet : pathPrefixSets) {
- results.add(new IdentityHashMap<AbstractResource, ResourceResolution>());
- }
- descendToFindResources(logger, pathPrefixSets, results, dir, "");
- return results;
- }
-
- @Override
public Map<AbstractResource, ResourceResolution> findApplicableResources(TreeLogger logger,
PathPrefixSet pathPrefixSet) {
if (!WATCH_FILE_CHANGES) {
@@ -150,7 +137,7 @@
DirectoryPathPrefixChangeManager.getAndClearChangedFiles(this, pathPrefixSet);
for (File changedFile : changedFiles) {
String changedRelativePath = Util.makeRelativePath(dir, changedFile);
- FileResource resource = FileResource.create(this, changedRelativePath, changedFile);
+ FileResource resource = FileResource.of(changedRelativePath, changedFile);
if (!changedFile.exists()) {
if (resolutionsByResource.containsKey(resource)) {
@@ -229,7 +216,7 @@
ResourceResolution resourceResolution = null;
if ((resourceResolution = pathPrefixSets.get(i).includesResource(childPath)) != null) {
Messages.INCLUDING_FILE.log(logger, childPath, null);
- FileResource r = FileResource.create(this, childPath, child);
+ FileResource r = FileResource.of(childPath, child);
results.get(i).put(r, resourceResolution);
} else {
Messages.EXCLUDING_FILE.log(logger, childPath, null);
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/FileResource.java b/dev/core/src/com/google/gwt/dev/resource/impl/FileResource.java
index 9ca55b3..46174e3 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/FileResource.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/FileResource.java
@@ -15,58 +15,44 @@
*/
package com.google.gwt.dev.resource.impl;
-import com.google.gwt.thirdparty.guava.common.collect.Maps;
+import com.google.gwt.thirdparty.guava.common.collect.MapMaker;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.lang.ref.WeakReference;
-import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
/**
* Represents a resource contained in a directory on a file system.
- * <p>
- * The class is immutable and automatically interned.
+ * <p>The class is immutable and automatically interned.
*/
public class FileResource extends AbstractResource {
+ /*
+ * The #equals and #hashCode is locked to work on identities by the base class Resource.
+ * Without interning, it would be impractical to use this class as a key in a map.
+ */
- private static Map<String, FileResource> fileResourceByKey = Maps.newHashMap();
+ private static final ConcurrentMap<String, FileResource> canonicalFileResources =
+ new MapMaker().weakValues().makeMap();
- public static FileResource create(DirectoryClassPathEntry classPathEntry, String abstractPathName,
- File file) {
- // Intern the file resource.
- String classPathLocation = classPathEntry != null ? classPathEntry.getLocation() : "null";
- String key = classPathLocation + File.pathSeparator + abstractPathName + File.pathSeparator
- + file.getAbsolutePath();
- FileResource fileResource = fileResourceByKey.get(key);
- if (fileResource == null) {
- fileResource = new FileResource(classPathEntry, abstractPathName, file);
- fileResourceByKey.put(key, fileResource);
- }
-
- return fileResource;
+ public static FileResource of(String abstractPathName, File file) {
+ String key = abstractPathName + "@" + file.getAbsolutePath();
+ FileResource sample = new FileResource(abstractPathName, file);
+ FileResource canonical = canonicalFileResources.putIfAbsent(key, sample);
+ return (canonical == null) ? sample : canonical;
}
private final String abstractPathName;
- private final WeakReference<DirectoryClassPathEntry> classPathEntryReference;
private final File file;
- private FileResource(DirectoryClassPathEntry classPathEntry, String abstractPathName, File file) {
+ private FileResource(String abstractPathName, File file) {
assert (file.isFile()) : file + " is not a file.";
- this.classPathEntryReference = new WeakReference<DirectoryClassPathEntry>(classPathEntry);
this.abstractPathName = abstractPathName;
this.file = file;
}
@Override
- public DirectoryClassPathEntry getClassPathEntry() {
- DirectoryClassPathEntry classPathEntry = classPathEntryReference.get();
- assert classPathEntry != null;
- return classPathEntry;
- }
-
- @Override
public long getLastModified() {
return file.lastModified();
}
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 6b0f5d2..3cd1026 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
@@ -78,11 +78,6 @@
}
@Override
- public ClassPathEntry getClassPathEntry() {
- return resource.getClassPathEntry();
- }
-
- @Override
public long getLastModified() {
return resource.getLastModified();
}
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/UrlResource.java b/dev/core/src/com/google/gwt/dev/resource/impl/UrlResource.java
index d4608e5..7dd5642 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/UrlResource.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/UrlResource.java
@@ -36,11 +36,6 @@
}
@Override
- public ClassPathEntry getClassPathEntry() {
- throw new UnsupportedOperationException("UrlResources do not come from the class path.");
- }
-
- @Override
public long getLastModified() {
return lastModified;
}
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileResource.java b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileResource.java
index f96186a..07ea34b 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileResource.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileResource.java
@@ -63,11 +63,6 @@
}
@Override
- public ZipFileClassPathEntry getClassPathEntry() {
- return classPathEntry;
- }
-
- @Override
public long getLastModified() {
return lastModified;
}
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/FileResourceTest.java b/dev/core/test/com/google/gwt/dev/resource/impl/FileResourceTest.java
index 4a48426..f74b744 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/FileResourceTest.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/FileResourceTest.java
@@ -21,7 +21,6 @@
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
/**
* Tests related FileResources.
@@ -29,19 +28,9 @@
public class FileResourceTest extends TestCase {
public void testBasic() {
- File f = null;
- try {
- f = File.createTempFile("com.google.gwt.dev.javac.impl.FileResourceTest",
- ".tmp");
- f.deleteOnExit();
- Util.writeStringAsFile(f, "contents 1");
- } catch (IOException e) {
- fail("Failed to create test file");
- }
+ File f = createTempFile();
- File dir = f.getParentFile();
- DirectoryClassPathEntry cpe = new DirectoryClassPathEntry(dir);
- FileResource r = FileResource.create(cpe, f.getName(), f);
+ FileResource r = FileResource.of(f.getName(), f);
assertEquals(f.getAbsoluteFile().toURI().toString(), r.getLocation());
/*
@@ -52,19 +41,9 @@
}
public void testDeletion() {
- File f = null;
- try {
- f = File.createTempFile("com.google.gwt.dev.javac.impl.FileResourceTest",
- ".tmp");
- f.deleteOnExit();
- Util.writeStringAsFile(f, "contents 1");
- } catch (IOException e) {
- fail("Failed to create test file");
- }
+ File f = createTempFile();
- File dir = f.getParentFile();
- DirectoryClassPathEntry cpe = new DirectoryClassPathEntry(dir);
- FileResource r = FileResource.create(cpe, f.getName(), f);
+ FileResource r = FileResource.of(f.getName(), f);
assertEquals(f.getAbsoluteFile().toURI().toString(), r.getLocation());
/*
@@ -80,11 +59,31 @@
* The resource is no longer available. Check to make sure we can't access its contents
* through the API.
*/
- InputStream in = null;
try {
- in = r.openContents();
+ r.openContents();
fail("Open contents unexpectedly succeeded.");
} catch (IOException expected) {
}
}
+
+ public void testInterning() throws Exception {
+ File f = createTempFile();
+
+ assertSame(FileResource.of(f.getName(), f), FileResource.of(f.getName(), f));
+ // A different FileResourse will return even files match if the pathname is different.
+ assertNotSame(FileResource.of(f.getName(), f), FileResource.of(f.getName() + "x", f));
+ }
+
+ private File createTempFile() {
+ File f = null;
+ try {
+ f = File.createTempFile("com.google.gwt.dev.javac.impl.FileResourceTest", ".tmp");
+ f.deleteOnExit();
+ Util.writeStringAsFile(f, "contents 1");
+ } catch (IOException e) {
+ fail("Failed to create test file");
+ }
+ return f;
+ }
+
}
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/MockAbstractResource.java b/dev/core/test/com/google/gwt/dev/resource/impl/MockAbstractResource.java
index 6c8c756..fbe9235 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/MockAbstractResource.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/MockAbstractResource.java
@@ -33,11 +33,6 @@
}
@Override
- public ClassPathEntry getClassPathEntry() {
- return mockClassPathEntry;
- }
-
- @Override
public long getLastModified() {
return 0;
}
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 0691588..c19ea92 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
@@ -111,8 +111,11 @@
public void assertPathIncluded(String expectedPath, ClassPathEntry expectedCpe) {
AbstractResource resource = findResourceWithPath(expectedPath);
assertNotNull(resource);
- ClassPathEntry actualCpe = resource.getClassPathEntry();
- assertEquals(expectedCpe.getLocation(), actualCpe.getLocation());
+ if (expectedCpe.getLocation().endsWith(".jar")) {
+ assertTrue(resource.getLocation().startsWith("jar:" + expectedCpe.getLocation()));
+ } else {
+ assertTrue(resource.getLocation().startsWith(expectedCpe.getLocation()));
+ }
}
public void assertPathNotIncluded(String path) {