Change ResourceGeneratorUtil to fall back to loading resources from the classpath if they cannot be found in the ResourceOracle.
This ensures that ClientBundle can be used with resources that are not within the module's source path.

Patch by: bobv
Review by: jat

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5577 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 a55c2d8..0081dd5 100644
--- a/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java
+++ b/user/src/com/google/gwt/resources/ext/ResourceGeneratorUtil.java
@@ -130,6 +130,10 @@
    * This method is sensitive to the <code>locale</code> deferred-binding
    * property and will attempt to use a best-match lookup by removing locale
    * components.
+   * <p>
+   * Loading through a ClassLoader with this method is much slower than the
+   * other <code>findResources</code> methods which make use of the compiler's
+   * ResourceOracle.
    * 
    * @param logger a TreeLogger that will be used to report errors or warnings
    * @param context the ResourceContext in which the ResourceGenerator is
@@ -141,15 +145,11 @@
    *          specified, using the name of the method and each of supplied
    *          extensions in the order in which they are specified
    * @return URLs for each {@link Source} annotation value defined on the
-   *         method, or an empty array if no sources could be found.
+   *         method.
    * @throws UnableToCompleteException if ore or more of the sources could not
    *           be found. The error will be reported via the <code>logger</code>
    *           provided to this method
-   * @deprecated Loading through a ClassLoader with this method is much slower
-   *             than the other <code>findResources</code> methods which make
-   *             use of the compiler's ResourceOracle.
    */
-  @Deprecated
   public static URL[] findResources(TreeLogger logger, ClassLoader classLoader,
       ResourceContext context, JMethod method, String[] defaultSuffixes)
       throws UnableToCompleteException {
@@ -167,15 +167,17 @@
    * components.
    * <p>
    * The compiler's ResourceOracle will be used to resolve resource locations.
-   * If it is necessary to alter the manner in which resources are resolved, use
-   * the overload that accepts an arbitrary ClassLoader.
+   * If the desired resource cannot be found in the ResourceOracle, this method
+   * will fall back to using the current thread's context ClassLoader. If it is
+   * necessary to alter the way in which resources are located, use the overload
+   * that accepts a ClassLoader.
    * 
    * @param logger a TreeLogger that will be used to report errors or warnings
    * @param context the ResourceContext in which the ResourceGenerator is
    *          operating
    * @param method the method to examine for {@link Source} annotations
    * @return URLs for each {@link Source} annotation value defined on the
-   *         method, or an empty array if no sources could be found.
+   *         method.
    * @throws UnableToCompleteException if ore or more of the sources could not
    *           be found. The error will be reported via the <code>logger</code>
    *           provided to this method
@@ -195,8 +197,10 @@
    * components.
    * <p>
    * The compiler's ResourceOracle will be used to resolve resource locations.
-   * If it is necessary to alter the manner in which resources are resolved, use
-   * the overload that accepts an arbitrary ClassLoader.
+   * If the desired resource cannot be found in the ResourceOracle, this method
+   * will fall back to using the current thread's context ClassLoader. If it is
+   * necessary to alter the way in which resources are located, use the overload
+   * that accepts a ClassLoader.
    * 
    * @param logger a TreeLogger that will be used to report errors or warnings
    * @param context the ResourceContext in which the ResourceGenerator is
@@ -207,7 +211,7 @@
    *          specified, using the name of the method and each of supplied
    *          extensions in the order in which they are specified
    * @return URLs for each {@link Source} annotation value defined on the
-   *         method, or an empty array if no sources could be found.
+   *         method.
    * @throws UnableToCompleteException if ore or more of the sources could not
    *           be found. The error will be reported via the <code>logger</code>
    *           provided to this method
@@ -215,9 +219,16 @@
   public static URL[] findResources(TreeLogger logger, ResourceContext context,
       JMethod method, String[] defaultSuffixes)
       throws UnableToCompleteException {
-    return findResources(logger, new ResourceOracleLocator(
-        context.getGeneratorContext().getResourcesOracle()), context, method,
-        defaultSuffixes);
+    try {
+      return findResources(logger, new ResourceOracleLocator(
+          context.getGeneratorContext().getResourcesOracle()), context, method,
+          defaultSuffixes);
+
+    } catch (UnableToCompleteException e) {
+      return findResources(logger,
+          Thread.currentThread().getContextClassLoader(), context, method,
+          defaultSuffixes);
+    }
   }
 
   /**
diff --git a/user/test/com/google/gwt/resources/client/TextResourceTest.java b/user/test/com/google/gwt/resources/client/TextResourceTest.java
index ffeaca8..aca11fd 100644
--- a/user/test/com/google/gwt/resources/client/TextResourceTest.java
+++ b/user/test/com/google/gwt/resources/client/TextResourceTest.java
@@ -23,8 +23,6 @@
  */
 public class TextResourceTest extends GWTTestCase {
 
-  private static final String HELLO = "Hello World!";
-
   static interface Resources extends ClientBundleWithLookup {
     @Source("com/google/gwt/resources/client/hello.txt")
     TextResource helloWorldAbsolute();
@@ -32,10 +30,15 @@
     @Source("hello.txt")
     ExternalTextResource helloWorldExternal();
 
+    @Source("com/google/gwt/resources/server/outside_resource_oracle.txt")
+    TextResource helloWorldOutsideResourceOracle();
+
     @Source("hello.txt")
     TextResource helloWorldRelative();
   }
 
+  private static final String HELLO = "Hello World!";
+
   @Override
   public String getModuleName() {
     return "com.google.gwt.resources.Resources";
@@ -75,6 +78,11 @@
     assertEquals("helloWorldExternal", r.helloWorldExternal().getName());
 
     ResourcePrototype[] resources = r.getResources();
-    assertEquals(3, resources.length);
+    assertEquals(4, resources.length);
+  }
+
+  public void testOutsideResourceOracle() {
+    Resources r = GWT.create(Resources.class);
+    assertTrue(r.helloWorldOutsideResourceOracle().getText().startsWith(HELLO));
   }
 }
diff --git a/user/test/com/google/gwt/resources/server/outside_resource_oracle.txt b/user/test/com/google/gwt/resources/server/outside_resource_oracle.txt
new file mode 100644
index 0000000..ade02db
--- /dev/null
+++ b/user/test/com/google/gwt/resources/server/outside_resource_oracle.txt
@@ -0,0 +1,4 @@
+Hello World!
+
+This file should be placed outside of the test module's source and public path
+to test fallback from ResourceOracle to the ClassLoader.
\ No newline at end of file