Allow plugin resources to be loaded from an alt location.

Added a development flag to allow firebase_tutorial_bundle.xml
and other resource files to be loaded from a local directory.
Previously, they had to be embedded in the code.
Techwriters requested this to reduce their cycle time on edits.

Bug: 28986011
Change-Id: Ib9b47086590b3e5127332ad227a6e5fc824fb273
diff --git a/src/com/google/services/creators/FileServiceCreators.java b/src/com/google/services/creators/FileServiceCreators.java
index 451bc6b..7aac356 100644
--- a/src/com/google/services/creators/FileServiceCreators.java
+++ b/src/com/google/services/creators/FileServiceCreators.java
@@ -18,13 +18,13 @@
 import com.android.tools.idea.structure.services.DeveloperServiceCreator;
 import com.android.tools.idea.structure.services.DeveloperServiceCreators;
 import com.android.tools.idea.structure.services.ServiceBundle;
+import com.google.api.client.repackaged.com.google.common.base.Strings;
+import com.intellij.openapi.diagnostic.Logger;
 import org.jetbrains.annotations.NotNull;
 
 import javax.xml.bind.JAXBException;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
+import java.io.*;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -36,6 +36,9 @@
  */
 public abstract class FileServiceCreators implements DeveloperServiceCreators {
 
+  @NotNull
+  private static final String ENABLE_ALTERNATE_RESOURCE_LOCATION_FLAG = "com.google.services.resource_location";
+
   protected abstract DeveloperServiceCreator getServiceCreator(final String resourceRoot,
                                                                final List<String> resources);
 
@@ -55,12 +58,47 @@
   }
 
   /**
+   * Retrieves a resource from the classloader's classpath.
+   *
+   * If the {@link #ENABLE_ALTERNATE_RESOURCE_LOCATION_FLAG} was set for the JVM running Studio it will attempt to find the resource at that
+   * location first.
+   */
+  protected URL getResource(String resourceName) {
+    String alternateResourceParameter = System.getProperty(ENABLE_ALTERNATE_RESOURCE_LOCATION_FLAG);
+    if (!Strings.isNullOrEmpty(alternateResourceParameter)) {
+      File altResourceDir = new File(alternateResourceParameter);
+      if (altResourceDir.exists() && altResourceDir.isDirectory()) {
+        File altResourceFile = new File(altResourceDir, resourceName);
+        if (altResourceFile.exists() && altResourceFile.isFile()) {
+          try {
+            return altResourceFile.toURI().toURL();
+          }
+          catch (MalformedURLException ignored) {
+          }
+        }
+        else {
+          getLog().warn("Alt resource loading flag was set, but '" + altResourceFile.getAbsolutePath() +
+                        "' wasn't found so failing back to standard logic");
+        }
+      }
+      else {
+        getLog().warn("Alt resource loading flag was set to '" + altResourceDir + "', but that doesn't appear to be a valid directory");
+      }
+    }
+    return getClass().getResource(resourceName);
+  }
+
+  private static Logger getLog() {
+    return Logger.getInstance(FileServiceCreators.class);
+  }
+
+  /**
    * Read list of {@code GoogleServiceCreators} from {@code getResourceConfigFileName()}.
    */
   private Collection<DeveloperServiceCreator> loadCreators() throws FileNotFoundException {
     String fileName = getResourceConfigFileName();
 
-    URL resource = getClass().getResource(fileName);
+    URL resource = getResource(fileName);
     if (resource == null) {
       throw new FileNotFoundException(String.format("Could not find service file %1$s", fileName));
     }