diff options
author | brettchabot <brettchabot@google.com> | 2019-03-20 12:19:48 -0700 |
---|---|---|
committer | Copybara Robolectric Bot <copybara-robolectric@google.com> | 2019-03-20 12:20:34 -0700 |
commit | b5e63df86dc758aa8c26c047a0762d1426992d6c (patch) | |
tree | 6b9ffd155e83dccc96c5b30f32cea5f2e565612c /shadowapi | |
parent | 04db5d5137738856e2c76022432c9745fab79d5f (diff) | |
download | robolectric-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.java | 64 |
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); + } + } +} |