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