aboutsummaryrefslogtreecommitdiff
path: root/shadowapi
diff options
context:
space:
mode:
authorbrettchabot <brettchabot@google.com>2019-03-20 12:19:48 -0700
committerCopybara Robolectric Bot <copybara-robolectric@google.com>2019-03-20 12:20:34 -0700
commitb5e63df86dc758aa8c26c047a0762d1426992d6c (patch)
tree6b9ffd155e83dccc96c5b30f32cea5f2e565612c /shadowapi
parent04db5d5137738856e2c76022432c9745fab79d5f (diff)
downloadrobolectric-b5e63df86dc758aa8c26c047a0762d1426992d6c.tar.gz
Move ConfigurationRegistry into shadowsapi
PiperOrigin-RevId: 239449649
Diffstat (limited to 'shadowapi')
-rw-r--r--shadowapi/src/main/java/org/robolectric/config/ConfigurationRegistry.java64
1 files changed, 64 insertions, 0 deletions
diff --git a/shadowapi/src/main/java/org/robolectric/config/ConfigurationRegistry.java b/shadowapi/src/main/java/org/robolectric/config/ConfigurationRegistry.java
new file mode 100644
index 000000000..7291416c4
--- /dev/null
+++ b/shadowapi/src/main/java/org/robolectric/config/ConfigurationRegistry.java
@@ -0,0 +1,64 @@
+package org.robolectric.config;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Holds configuration objects for the current test, computed using
+ * {@link Configurer}.
+ *
+ * Configuration is computed before tests run, outside of their sandboxes. If the configuration
+ * is needed from within a sandbox (when a test is executing), we need to transfer it to a class
+ * that the SandboxClassLoader recognizes. We do this by serializing and deserializing in
+ * {@link #reloadInSandboxClassLoader(Object)}.
+ */
+public class ConfigurationRegistry {
+
+ public static ConfigurationRegistry instance;
+
+ /**
+ * Returns the configuration object of the specified class, computed using
+ * {@link Configurer}.
+ */
+ public static <T> T get(Class<T> configClass) {
+ return instance.getInSandboxClassLoader(configClass);
+ }
+
+ private final Map<String, Object> configurations = new HashMap<>();
+
+ public ConfigurationRegistry(Map<Class<?>, Object> configClassMap) {
+ for (Class<?> classInParentLoader : configClassMap.keySet()) {
+ Object configInParentLoader = configClassMap.get(classInParentLoader);
+ configurations.put(classInParentLoader.getName(), configInParentLoader);
+ }
+ }
+
+ private <T> T getInSandboxClassLoader(Class<T> someConfigClass) {
+ Object configInParentLoader = configurations.get(someConfigClass.getName());
+ Object configInSandboxLoader = reloadInSandboxClassLoader(configInParentLoader);
+ return someConfigClass.cast(configInSandboxLoader);
+ }
+
+ private static Object reloadInSandboxClassLoader(Object configInParentLoader) {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ try (ObjectOutputStream out = new ObjectOutputStream(buf)) {
+ out.writeObject(configInParentLoader);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ byte[] bytes = buf.toByteArray();
+
+ // ObjectInputStream loads classes in the current classloader by magic
+ try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
+ return in.readObject();
+ } catch (IOException | ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}