Home | History | Annotate | Download | only in bytecode
      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 
     15   public Sandbox(ClassLoader robolectricClassLoader) {
     16     this.robolectricClassLoader = robolectricClassLoader;
     17   }
     18 
     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   }
     26   public ClassLoader getRobolectricClassLoader() {
     27     return robolectricClassLoader;
     28   }
     29 
     30   private ShadowInvalidator getShadowInvalidator() {
     31     if (shadowInvalidator == null) {
     32       this.shadowInvalidator = new ShadowInvalidator();
     33     }
     34     return shadowInvalidator;
     35   }
     36 
     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 
     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