1 package org.robolectric.internal.bytecode;
2 
3 import static org.robolectric.util.ReflectionHelpers.newInstance;
4 import static org.robolectric.util.ReflectionHelpers.setStaticField;
5 
6 import java.util.Set;
7 import org.robolectric.shadow.api.Shadow;
8 
9 public class Sandbox {
10   private final ClassLoader robolectricClassLoader;
11   private ShadowInvalidator shadowInvalidator;
12   public ClassHandler classHandler; // todo not public
13   private ShadowMap shadowMap = ShadowMap.EMPTY;
14 
Sandbox(ClassLoader robolectricClassLoader)15   public Sandbox(ClassLoader robolectricClassLoader) {
16     this.robolectricClassLoader = robolectricClassLoader;
17   }
18 
bootstrappedClass(Class<?> clazz)19   public <T> Class<T> bootstrappedClass(Class<?> clazz) {
20     try {
21       return (Class<T>) robolectricClassLoader.loadClass(clazz.getName());
22     } catch (ClassNotFoundException e) {
23       throw new RuntimeException(e);
24     }
25   }
getRobolectricClassLoader()26   public ClassLoader getRobolectricClassLoader() {
27     return robolectricClassLoader;
28   }
29 
getShadowInvalidator()30   private ShadowInvalidator getShadowInvalidator() {
31     if (shadowInvalidator == null) {
32       this.shadowInvalidator = new ShadowInvalidator();
33     }
34     return shadowInvalidator;
35   }
36 
replaceShadowMap(ShadowMap shadowMap)37   public void replaceShadowMap(ShadowMap shadowMap) {
38     if (InvokeDynamic.ENABLED) {
39       ShadowMap oldShadowMap = this.shadowMap;
40       this.shadowMap = shadowMap;
41       Set<String> invalidatedClasses = shadowMap.getInvalidatedClasses(oldShadowMap);
42       getShadowInvalidator().invalidateClasses(invalidatedClasses);
43     }
44   }
45 
configure(ClassHandler classHandler, Interceptors interceptors)46   public void configure(ClassHandler classHandler, Interceptors interceptors) {
47     this.classHandler = classHandler;
48 
49     ClassLoader robolectricClassLoader = getRobolectricClassLoader();
50     Class<?> robolectricInternalsClass = bootstrappedClass(RobolectricInternals.class);
51     if (InvokeDynamic.ENABLED) {
52       ShadowInvalidator invalidator = getShadowInvalidator();
53       setStaticField(robolectricInternalsClass, "shadowInvalidator", invalidator);
54     }
55 
56     setStaticField(robolectricInternalsClass, "classHandler", classHandler);
57     setStaticField(robolectricInternalsClass, "classLoader", robolectricClassLoader);
58 
59     Class<?> invokeDynamicSupportClass = bootstrappedClass(InvokeDynamicSupport.class);
60     setStaticField(invokeDynamicSupportClass, "INTERCEPTORS", interceptors);
61 
62     Class<?> shadowClass = bootstrappedClass(Shadow.class);
63     setStaticField(shadowClass, "SHADOW_IMPL", newInstance(bootstrappedClass(ShadowImpl.class)));
64   }
65 }
66