Allow arbitrary Files to be injected into the ClientBundle source lookup mechanism.
Patch by: bobv
Review by: rjrjr
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6017 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java b/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java
index 0c92052..d2efb20 100644
--- a/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java
+++ b/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java
@@ -25,9 +25,12 @@
import com.google.gwt.core.ext.typeinfo.JPackage;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.resource.ResourceOracle;
+import com.google.gwt.dev.util.collect.Maps;
import com.google.gwt.resources.client.ClientBundle.Source;
+import java.io.File;
import java.lang.annotation.Annotation;
+import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
@@ -52,6 +55,30 @@
}
/**
+ * A locator which will use files published via
+ * {@link ResourceGeneratorUtil#addNamedFile(String, File)}.
+ */
+ private static class FileLocator implements Locator {
+ public static final FileLocator INSTANCE = new FileLocator();
+
+ private FileLocator() {
+ }
+
+ public URL locate(String resourceName) {
+ File f = namedFiles.get(resourceName);
+ if (f != null && f.isFile() && f.canRead()) {
+ try {
+ return f.toURI().toURL();
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("Unable to make a URL for file "
+ + f.getName());
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
* Wrapper interface around different strategies for loading resource data.
*/
private interface Locator {
@@ -71,6 +98,8 @@
}
}
+ private static Map<String, File> namedFiles = Maps.create();
+
/**
* These are type names from previous APIs or from APIs with similar
* functionality that might be confusing.
@@ -112,6 +141,25 @@
}
/**
+ * Publish or override resources named by {@link Source} annotations. This
+ * method is intended to be called by Generators that create ClientBundle
+ * instances and need to pass source data to the ClientBundle system that is
+ * not accessible through the classpath.
+ *
+ * @param resourceName the path at which the contents of <code>file</code>
+ * should be made available
+ * @param file the File whose contents are to be provided to the ClientBundle
+ * system
+ */
+ public static void addNamedFile(String resourceName, File file) {
+ assert resourceName != null : "resourceName";
+ assert file != null : "file";
+ assert file.isFile() && file.canRead() : "file does not exist or cannot be read";
+
+ namedFiles = Maps.put(namedFiles, resourceName, file);
+ }
+
+ /**
* Return the base filename of a resource. The behavior is similar to the unix
* command <code>basename</code>.
*
@@ -233,14 +281,24 @@
public static URL[] findResources(TreeLogger logger, ResourceContext context,
JMethod method, String[] defaultSuffixes)
throws UnableToCompleteException {
+ URL[] toReturn = null;
+ Locator locator;
- // Try to find the resources with ResourceOracle
- Locator locator = new ResourceOracleLocator(
- context.getGeneratorContext().getResourcesOracle());
+ // If we have named files, attempt them first
+ if (!namedFiles.isEmpty()) {
+ toReturn = findResources(logger, FileLocator.INSTANCE, context, method,
+ defaultSuffixes, false);
+ }
- // Don't report errors since we have a fallback mechanism
- URL[] toReturn = findResources(logger, locator, context, method,
- defaultSuffixes, false);
+ if (toReturn == null) {
+ // Try to find the resources with ResourceOracle
+ locator = new ResourceOracleLocator(
+ context.getGeneratorContext().getResourcesOracle());
+
+ // Don't report errors since we have a fallback mechanism
+ toReturn = findResources(logger, locator, context, method,
+ defaultSuffixes, false);
+ }
if (toReturn == null) {
// Since not all resources were found, try with ClassLoader