Config.java revision 23a26cc3e5b33c0503a99847292ac99817f5af43
1cfb3d242306311ce27ec51bf511764377c173a7cKiran Ryali + Christian Williamspackage org.robolectric.annotation; 2dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao 3f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport org.jetbrains.annotations.NotNull; 4f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 5f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Annotation; 6f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Documented; 7f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.ElementType; 8f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Retention; 9f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.RetentionPolicy; 10f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.lang.annotation.Target; 11f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.util.ArrayList; 12f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williamsimport java.util.Arrays; 1323a26cc3e5b33c0503a99847292ac99817f5af43Christian Williamsimport java.util.Properties; 14f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 15dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao/** 1680c8a1718d42c7e2165289a7bbfab5e7f3dc0513Christian Williams & Dimitris Couchell * Indicate that robolectric should look for values that is specific by those qualifiers 17dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao */ 18f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Documented 19f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Retention(RetentionPolicy.RUNTIME) 20f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams@Target({ElementType.TYPE, ElementType.METHOD}) 217be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williamspublic @interface Config { 2248f95f3e0955035946f7c416dec56219a9b19886Christian Williams @SuppressWarnings("UnusedDeclaration") 2348f95f3e0955035946f7c416dec56219a9b19886Christian Williams public static final String NONE = "--none"; 2448f95f3e0955035946f7c416dec56219a9b19886Christian Williams public static final String DEFAULT = "--default"; 257be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williams 267be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williams /** 278084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams * The Android SDK level to emulate. If not specified, Robolectric defaults to the targetSdkVersion in your app's manifest. 2813e56890ba2f0206bc4d68fb536484c9ae287e1eChristian Williams * 2913e56890ba2f0206bc4d68fb536484c9ae287e1eChristian Williams * Not yet supported as of Robolectric 2.0. 307be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williams */ 318084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams int emulateSdk() default -1; 327be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williams 338084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams /** 3448f95f3e0955035946f7c416dec56219a9b19886Christian Williams * The Android manifest file to load; Robolectric will look relative to the current directory. 3548f95f3e0955035946f7c416dec56219a9b19886Christian Williams * Resources and assets will be loaded relative to the manifest. 3648f95f3e0955035946f7c416dec56219a9b19886Christian Williams * 3748f95f3e0955035946f7c416dec56219a9b19886Christian Williams * If not specified, Robolectric defaults to {@code AndroidManifest.xml}. 3848f95f3e0955035946f7c416dec56219a9b19886Christian Williams * 3948f95f3e0955035946f7c416dec56219a9b19886Christian Williams * If your project has no manifest or resources, use {@link Config#NONE}. 4048f95f3e0955035946f7c416dec56219a9b19886Christian Williams */ 4148f95f3e0955035946f7c416dec56219a9b19886Christian Williams String manifest() default DEFAULT; 4248f95f3e0955035946f7c416dec56219a9b19886Christian Williams 4348f95f3e0955035946f7c416dec56219a9b19886Christian Williams /** 448084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams * Qualifiers for the resource resolution, such as "fr-normal-port-hdpi". 4513e56890ba2f0206bc4d68fb536484c9ae287e1eChristian Williams * 4613e56890ba2f0206bc4d68fb536484c9ae287e1eChristian Williams * @see <a href="http://developer.android.com/guide/topics/resources/providing-resources.html">Providing Resources</a> in the Android Developer docs for more information. 478084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams */ 488084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams String qualifiers() default ""; 497be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williams 508084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams /** 518084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams * The Android SDK level to report in Build.VERSION.SDK_INT. 5213e56890ba2f0206bc4d68fb536484c9ae287e1eChristian Williams * 5313e56890ba2f0206bc4d68fb536484c9ae287e1eChristian Williams * @see <a href="http://en.wikipedia.org/wiki/Android_version_history">Android Version History</a>. 548084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams */ 557be4d2ba0e45483ad70cbd994955ae1b70afafdcKiran Ryali + Christian Williams int reportSdk() default -1; 568084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams 578084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams /** 588084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams * A list of shadow classes to enable, in addition to those that are already present. 598084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams */ 608084b47f2133fc32630fabb46f2e8a259bcd8735Christian Williams Class<?>[] shadows() default {}; 61f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 62f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams public class Implementation implements Config { 63f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams private final int emulateSdk; 6448f95f3e0955035946f7c416dec56219a9b19886Christian Williams private final String manifest; 65f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams private final String qualifiers; 66f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams private final int reportSdk; 67f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams private final Class<?>[] shadows; 68f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 6923a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams public static Config fromProperties(Properties configProperties) { 7023a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams if (configProperties == null || configProperties.size() == 0) return null; 7123a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams return new Implementation( 7223a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams Integer.parseInt(configProperties.getProperty("emulateSdk", "-1")), 7323a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams configProperties.getProperty("manifest", DEFAULT), 7423a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams configProperties.getProperty("qualifiers", ""), 7523a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams Integer.parseInt(configProperties.getProperty("reportSdk", "-1")), 7623a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams parseClasses(configProperties.getProperty("shadows", "")) 7723a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams ); 7823a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams } 7923a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams 8023a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams private static Class<?>[] parseClasses(String classList) { 8123a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams String[] classNames = classList.split("[, ]+"); 8223a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams Class[] classes = new Class[classNames.length]; 8323a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams for (int i = 0; i < classNames.length; i++) { 8423a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams try { 8523a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams classes[i] = Implementation.class.getClassLoader().loadClass(classNames[i]); 8623a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams } catch (ClassNotFoundException e) { 8723a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams throw new RuntimeException(e); 8823a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams } 8923a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams } 9023a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams return classes; 9123a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams } 9223a26cc3e5b33c0503a99847292ac99817f5af43Christian Williams 9348f95f3e0955035946f7c416dec56219a9b19886Christian Williams public Implementation(int emulateSdk, String manifest, String qualifiers, int reportSdk, Class<?>[] shadows) { 94f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams this.emulateSdk = emulateSdk; 9548f95f3e0955035946f7c416dec56219a9b19886Christian Williams this.manifest = manifest; 96f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams this.qualifiers = qualifiers; 97f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams this.reportSdk = reportSdk; 98f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams this.shadows = shadows; 99f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 100f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 101f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams public Implementation(Config baseConfig, Config overlayConfig) { 102f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams this.emulateSdk = pick(baseConfig.emulateSdk(), overlayConfig.emulateSdk(), -1); 10348f95f3e0955035946f7c416dec56219a9b19886Christian Williams this.manifest = pick(baseConfig.manifest(), overlayConfig.manifest(), DEFAULT); 104f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams this.qualifiers = pick(baseConfig.qualifiers(), overlayConfig.qualifiers(), ""); 105f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams this.reportSdk = pick(baseConfig.reportSdk(), overlayConfig.reportSdk(), -1); 106f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams ArrayList<Class<?>> shadows = new ArrayList<Class<?>>(); 107f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams shadows.addAll(Arrays.asList(baseConfig.shadows())); 108f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams shadows.addAll(Arrays.asList(overlayConfig.shadows())); 109f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams this.shadows = shadows.toArray(new Class[shadows.size()]); 110f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 111f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 112f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams private <T> T pick(T baseValue, T overlayValue, T nullValue) { 113f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams return overlayValue.equals(nullValue) ? baseValue : overlayValue; 114f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 115f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 116f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams @Override public int emulateSdk() { 117f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams return emulateSdk; 118f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 119f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 12048f95f3e0955035946f7c416dec56219a9b19886Christian Williams @Override public String manifest() { 12148f95f3e0955035946f7c416dec56219a9b19886Christian Williams return manifest; 12248f95f3e0955035946f7c416dec56219a9b19886Christian Williams } 12348f95f3e0955035946f7c416dec56219a9b19886Christian Williams 124f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams @Override public String qualifiers() { 125f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams return qualifiers; 126f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 127f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 128f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams @Override public int reportSdk() { 129f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams return reportSdk; 130f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 131f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 132f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams @Override public Class<?>[] shadows() { 133f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams return shadows; 134f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 135f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 136f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams @NotNull @Override public Class<? extends Annotation> annotationType() { 137f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams return Config.class; 138f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 139f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 140f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams @Override 141f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams public boolean equals(Object o) { 142f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams if (this == o) return true; 143f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams if (o == null || getClass() != o.getClass()) return false; 144f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 145f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams Implementation other = (Implementation) o; 146f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 147f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams if (emulateSdk != other.emulateSdk) return false; 148f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams if (reportSdk != other.reportSdk) return false; 149f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams if (!qualifiers.equals(other.qualifiers)) return false; 150f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams if (!Arrays.equals(shadows, other.shadows)) return false; 151f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 152f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams return true; 153f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 154f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams 155f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams @Override 156f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams public int hashCode() { 157f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams int result = emulateSdk; 158f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams result = 31 * result + qualifiers.hashCode(); 159f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams result = 31 * result + reportSdk; 160f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams result = 31 * result + Arrays.hashCode(shadows); 161f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams return result; 162f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 163f6df8a55ac378dee35324bc865fb4d741dcb4824Christian Williams } 164dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao} 165