ResourceLoader.java revision aec1d0888fe04efd0cde7514e155870b18c41286
1a2043a8fff01f3e2d9a5e30dd1cf5fb6a5342f4dTyler Schultzpackage com.xtremelabs.robolectric.res;
247bd528af49de6d8459c8aeda60b88cc7a3c961fChristian Williams
3828b5524de2393f92fdd52204c16a75e608db62fPhil Goodwinimport android.R;
45ec776796c773be831b2fd1cfd940da663f6c4c3Phil Goodwin & Tyler Schultzimport android.content.Context;
5fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowhamimport android.graphics.drawable.AnimationDrawable;
6fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowhamimport android.graphics.drawable.ColorDrawable;
7fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowhamimport android.graphics.drawable.Drawable;
85ec242e7f4ba642abb5cc3dceee0dc49ce2f1a3fRich Humphreyimport android.preference.PreferenceScreen;
9b539366073ccb47433de7191dbbf519ed4ab2d8fPhil Goodwinimport android.view.Menu;
1025cbf6f16c0fc8e6524935e6fa3d70ec2a92ed25Phil Goodwin & Tyler Schultzimport android.view.View;
1125cbf6f16c0fc8e6524935e6fa3d70ec2a92ed25Phil Goodwin & Tyler Schultzimport android.view.ViewGroup;
12fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowhamimport com.xtremelabs.robolectric.Robolectric;
13fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowhamimport com.xtremelabs.robolectric.shadows.ShadowContextWrapper;
14bb2f85d397fa65f20c6932186d9156ced9beb184Michael Portuesiimport com.xtremelabs.robolectric.util.I18nException;
15d05d28aca7ef2f1eba0714fc46a2ed4165a5902aPhil Goodwinimport com.xtremelabs.robolectric.util.PropertiesHelper;
1670650f03fb9161ce77255654517d34b67232588eChristian Williams & Phil Goodwin
178900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richardimport java.io.*;
188900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richardimport java.lang.reflect.Field;
198900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richardimport java.util.HashMap;
208900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richardimport java.util.Map;
218900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richardimport java.util.Properties;
228900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richard
238900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richardimport static com.xtremelabs.robolectric.Robolectric.shadowOf;
248900025d7fa03579c0ae4d19255d3a8650cbf12aPhil Goodwin & Ryan Richard
2547bd528af49de6d8459c8aeda60b88cc7a3c961fChristian Williamspublic class ResourceLoader {
2648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private static final FileFilter MENU_DIR_FILE_FILTER = new FileFilter() {
2748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		@Override
2848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		public boolean accept( File file ) {
2948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return isMenuDirectory( file.getPath() );
3048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
3148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	};
3248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private static final FileFilter LAYOUT_DIR_FILE_FILTER = new FileFilter() {
3348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		@Override
3448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		public boolean accept( File file ) {
3548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return isLayoutDirectory( file.getPath() );
3648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
3748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	};
3848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private static final FileFilter DRAWABLE_DIR_FILE_FILTER = new FileFilter() {
3948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		@Override
4048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		public boolean accept( File file ) {
4148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return isDrawableDirectory( file.getPath() );
4248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
4348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	};
4448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
4548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private File resourceDir;
4648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private File assetsDir;
4748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private int sdkVersion;
4848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private Class rClass;
4948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
5048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final ResourceExtractor resourceExtractor;
5148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private ViewLoader viewLoader;
5248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private MenuLoader menuLoader;
5348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private PreferenceLoader preferenceLoader;
5448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final StringResourceLoader stringResourceLoader;
5548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final PluralResourceLoader pluralResourceLoader;
5648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final StringArrayResourceLoader stringArrayResourceLoader;
5748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final AttrResourceLoader attrResourceLoader;
5848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final ColorResourceLoader colorResourceLoader;
5948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final DrawableResourceLoader drawableResourceLoader;
6048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final RawResourceLoader rawResourceLoader;
6148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final DimenResourceLoader dimenResourceLoader;
6248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private final IntegerResourceLoader integerResourceLoader;
6348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private boolean isInitialized = false;
6448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private boolean strictI18n = false;
6548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
6648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	// TODO: get these value from the xml resources instead [xw 20101011]
6748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	/**
6848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	 * @deprecated
6948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	 */
7048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public final Map< Integer, Integer > dimensions = new HashMap< Integer, Integer >();
7148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
7248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public ResourceLoader( int sdkVersion, Class rClass, File resourceDir, File assetsDir ) throws Exception {
7348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		this.sdkVersion = sdkVersion;
7448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		this.assetsDir = assetsDir;
7548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		this.rClass = rClass;
7648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		resourceExtractor = new ResourceExtractor();
7748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		resourceExtractor.addLocalRClass( rClass );
7848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		resourceExtractor.addSystemRClass( R.class );
7948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
8048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		stringResourceLoader = new StringResourceLoader( resourceExtractor );
8148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		pluralResourceLoader = new PluralResourceLoader( resourceExtractor, stringResourceLoader );
8248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		stringArrayResourceLoader = new StringArrayResourceLoader( resourceExtractor, stringResourceLoader );
8348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		colorResourceLoader = new ColorResourceLoader( resourceExtractor );
8448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		attrResourceLoader = new AttrResourceLoader( resourceExtractor );
8548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		drawableResourceLoader = new DrawableResourceLoader( resourceExtractor, resourceDir );
8648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		rawResourceLoader = new RawResourceLoader( resourceExtractor, resourceDir );
8748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		dimenResourceLoader = new DimenResourceLoader( resourceExtractor );
8848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		integerResourceLoader = new IntegerResourceLoader( resourceExtractor );
8948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
9048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		this.resourceDir = resourceDir;
9148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
9248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
9348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public void setStrictI18n( boolean strict ) {
9448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		this.strictI18n = strict;
9548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( viewLoader != null ) {
9648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			viewLoader.setStrictI18n( strict );
9748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
9848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( menuLoader != null ) {
9948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			menuLoader.setStrictI18n( strict );
10048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
10148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( preferenceLoader != null ) {
10248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			preferenceLoader.setStrictI18n( strict );
10348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
10448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
10548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
10648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public boolean getStrictI18n() {
10748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return strictI18n;
10848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
10948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
11048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void init() {
11148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( isInitialized ) {
11248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return;
11348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
11448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
11548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		try {
11648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			if ( resourceDir != null ) {
11748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				viewLoader = new ViewLoader( resourceExtractor, attrResourceLoader );
11848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				menuLoader = new MenuLoader( resourceExtractor, attrResourceLoader );
11948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				preferenceLoader = new PreferenceLoader( resourceExtractor );
12048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
12148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				viewLoader.setStrictI18n( strictI18n );
12248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				menuLoader.setStrictI18n( strictI18n );
12348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				preferenceLoader.setStrictI18n( strictI18n );
12448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
12548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				File systemResourceDir = getSystemResourceDir( getPathToAndroidResources() );
12648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				File localValueResourceDir = getValueResourceDir( resourceDir );
12748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				File systemValueResourceDir = getValueResourceDir( systemResourceDir );
12848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				File preferenceDir = getPreferenceResourceDir( resourceDir );
12948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
13048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadStringResources( localValueResourceDir, systemValueResourceDir );
13148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadPluralsResources( localValueResourceDir, systemValueResourceDir );
13248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadValueResources( localValueResourceDir, systemValueResourceDir );
13348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadDimenResources( localValueResourceDir, systemValueResourceDir );
13448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadIntegerResource( localValueResourceDir, systemResourceDir );
13548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadViewResources( systemResourceDir, resourceDir );
13648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadMenuResources( resourceDir );
13748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadDrawableResources( resourceDir );
13848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				loadPreferenceResources( preferenceDir );
13948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
14048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			} else {
14148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				viewLoader = null;
14248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				menuLoader = null;
14348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				preferenceLoader = null;
14448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			}
14548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		} catch ( I18nException e ) {
14648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			throw e;
14748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		} catch ( Exception e ) {
14848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			throw new RuntimeException( e );
14948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
15048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		isInitialized = true;
15148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
15248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
15348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private File getSystemResourceDir( String pathToAndroidResources ) {
15448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return pathToAndroidResources != null ? new File( pathToAndroidResources ) : null;
15548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
15648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
15748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadStringResources( File localResourceDir, File systemValueResourceDir ) throws Exception {
15848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		DocumentLoader stringResourceDocumentLoader = new DocumentLoader( this.stringResourceLoader );
15948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadValueResourcesFromDirs( stringResourceDocumentLoader, localResourceDir, systemValueResourceDir );
16048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
16148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
16248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadPluralsResources( File localResourceDir, File systemValueResourceDir ) throws Exception {
16348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		DocumentLoader stringResourceDocumentLoader = new DocumentLoader( this.pluralResourceLoader );
16448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadValueResourcesFromDirs( stringResourceDocumentLoader, localResourceDir, systemValueResourceDir );
16548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
16648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
16748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadValueResources( File localResourceDir, File systemValueResourceDir ) throws Exception {
16848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		DocumentLoader valueResourceLoader = new DocumentLoader( stringArrayResourceLoader, colorResourceLoader,
16948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				attrResourceLoader );
17048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadValueResourcesFromDirs( valueResourceLoader, localResourceDir, systemValueResourceDir );
17148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
17248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
17348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadDimenResources( File localResourceDir, File systemValueResourceDir ) throws Exception {
17448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		DocumentLoader dimenResourceDocumentLoader = new DocumentLoader( this.dimenResourceLoader );
17548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadValueResourcesFromDirs( dimenResourceDocumentLoader, localResourceDir, systemValueResourceDir );
17648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
17748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
17848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadIntegerResource( File localResourceDir, File systemValueResourceDir ) throws Exception {
17948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		DocumentLoader integerResourceDocumentLoader = new DocumentLoader( this.integerResourceLoader );
18048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadValueResourcesFromDirs( integerResourceDocumentLoader, localResourceDir, systemValueResourceDir );
18148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
18248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
18348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadViewResources( File systemResourceDir, File xmlResourceDir ) throws Exception {
18448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		DocumentLoader viewDocumentLoader = new DocumentLoader( viewLoader );
18548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadLayoutResourceXmlSubDirs( viewDocumentLoader, xmlResourceDir, false );
18648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadLayoutResourceXmlSubDirs( viewDocumentLoader, systemResourceDir, true );
18748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
18848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
18948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadMenuResources( File xmlResourceDir ) throws Exception {
19048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		DocumentLoader menuDocumentLoader = new DocumentLoader( menuLoader );
19148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadMenuResourceXmlDirs( menuDocumentLoader, xmlResourceDir );
19248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
19348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
19448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadDrawableResources( File xmlResourceDir ) throws Exception {
19548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		DocumentLoader drawableDocumentLoader = new DocumentLoader( drawableResourceLoader );
19648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadDrawableResourceXmlDirs( drawableDocumentLoader, xmlResourceDir );
19748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
19848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
19948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadPreferenceResources( File xmlResourceDir ) throws Exception {
20048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( xmlResourceDir.exists() ) {
20148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			DocumentLoader preferenceDocumentLoader = new DocumentLoader( preferenceLoader );
20248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			preferenceDocumentLoader.loadResourceXmlDir( xmlResourceDir );
20348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
20448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
20548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
20648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadLayoutResourceXmlSubDirs( DocumentLoader layoutDocumentLoader, File xmlResourceDir, boolean isSystem )
20748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			throws Exception {
20848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( xmlResourceDir != null ) {
20948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			layoutDocumentLoader.loadResourceXmlDirs( isSystem, xmlResourceDir.listFiles( LAYOUT_DIR_FILE_FILTER ) );
21048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
21148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
21248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
21348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadMenuResourceXmlDirs( DocumentLoader menuDocumentLoader, File xmlResourceDir ) throws Exception {
21448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( xmlResourceDir != null ) {
21548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			menuDocumentLoader.loadResourceXmlDirs( xmlResourceDir.listFiles( MENU_DIR_FILE_FILTER ) );
21648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
21748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
21848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
21948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadDrawableResourceXmlDirs( DocumentLoader drawableResourceLoader, File xmlResourceDir ) throws Exception {
22048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( xmlResourceDir != null ) {
22148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			drawableResourceLoader.loadResourceXmlDirs( xmlResourceDir.listFiles( DRAWABLE_DIR_FILE_FILTER ) );
22248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
22348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
22448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
22548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadValueResourcesFromDirs( DocumentLoader documentLoader, File localValueResourceDir,
22648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			File systemValueResourceDir ) throws Exception {
22748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadValueResourcesFromDir( documentLoader, localValueResourceDir );
22848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		loadSystemResourceXmlDir( documentLoader, systemValueResourceDir );
22948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
23048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
23148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadValueResourcesFromDir( DocumentLoader documentloader, File xmlResourceDir ) throws Exception {
23248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( xmlResourceDir != null ) {
23348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			documentloader.loadResourceXmlDir( xmlResourceDir );
23448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
23548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
23648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
23748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private void loadSystemResourceXmlDir( DocumentLoader documentLoader, File stringResourceDir ) throws Exception {
23848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( stringResourceDir != null ) {
23948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			documentLoader.loadSystemResourceXmlDir( stringResourceDir );
24048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
24148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
24248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
24348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private File getValueResourceDir( File xmlResourceDir ) {
24448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return xmlResourceDir != null ? new File( xmlResourceDir, "values" ) : null;
24548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
24648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
24748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private File getPreferenceResourceDir( File xmlResourceDir ) {
24848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return xmlResourceDir != null ? new File( xmlResourceDir, "xml" ) : null;
24948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
25048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
25148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private String getPathToAndroidResources() {
25248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		String resourcePath;
25348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( ( resourcePath = getAndroidResourcePathFromLocalProperties() ) != null ) {
25448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return resourcePath;
25548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		} else if ( ( resourcePath = getAndroidResourcePathFromSystemEnvironment() ) != null ) {
25648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return resourcePath;
25748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		} else if ( ( resourcePath = getAndroidResourcePathFromSystemProperty() ) != null ) {
25848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return resourcePath;
25948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		} else if ( ( resourcePath = getAndroidResourcePathByExecingWhichAndroid() ) != null ) {
26048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return resourcePath;
26148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
26248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
26348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		System.out.println( "WARNING: Unable to find path to Android SDK" );
26448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return null;
26548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
26648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
26748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private String getAndroidResourcePathFromLocalProperties() {
26848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// Hand tested
26948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// This is the path most often taken by IntelliJ
27048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		File rootDir = resourceDir.getParentFile();
27148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		String localPropertiesFileName = "local.properties";
27248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		File localPropertiesFile = new File( rootDir, localPropertiesFileName );
27348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( !localPropertiesFile.exists() ) {
27448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			localPropertiesFile = new File( localPropertiesFileName );
27548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
27648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( localPropertiesFile.exists() ) {
27748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			Properties localProperties = new Properties();
27848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			try {
27948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				localProperties.load( new FileInputStream( localPropertiesFile ) );
28048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				PropertiesHelper.doSubstitutions( localProperties );
28148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				String sdkPath = localProperties.getProperty( "sdk.dir" );
28248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				if ( sdkPath != null ) {
28348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao					return getResourcePathFromSdkPath( sdkPath );
28448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				}
28548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			} catch ( IOException e ) {
28648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				// fine, we'll try something else
28748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			}
28848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
28948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return null;
29048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
29148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
29248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private String getAndroidResourcePathFromSystemEnvironment() {
29348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// Hand tested
29448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		String resourcePath = System.getenv().get( "ANDROID_HOME" );
29548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( resourcePath != null ) {
29648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return new File( resourcePath, getAndroidResourceSubPath() ).toString();
29748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
29848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return null;
29948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
30048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
30148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private String getAndroidResourcePathFromSystemProperty() {
30248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// this is used by the android-maven-plugin
30348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		String resourcePath = System.getProperty( "android.sdk.path" );
30448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( resourcePath != null ) {
30548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return new File( resourcePath, getAndroidResourceSubPath() ).toString();
30648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
30748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return null;
30848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
30948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
31048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private String getAndroidResourcePathByExecingWhichAndroid() {
31148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// Hand tested
31248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// Should always work from the command line. Often fails in IDEs because
31348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// they don't pass the full PATH in the environment
31448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		try {
31548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			Process process = Runtime.getRuntime().exec( new String[] { "which", "android" } );
31648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			String sdkPath = new BufferedReader( new InputStreamReader( process.getInputStream() ) ).readLine();
31748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			if ( sdkPath != null && sdkPath.endsWith( "tools/android" ) ) {
31848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				return getResourcePathFromSdkPath( sdkPath.substring( 0, sdkPath.indexOf( "tools/android" ) ) );
31948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			}
32048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		} catch ( IOException e ) {
32148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			// fine we'll try something else
32248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
32348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return null;
32448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
32548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
32648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private String getResourcePathFromSdkPath( String sdkPath ) {
32748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		File androidResourcePath = new File( sdkPath, getAndroidResourceSubPath() );
32848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return androidResourcePath.exists() ? androidResourcePath.toString() : null;
32948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
33048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
33148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	private String getAndroidResourceSubPath() {
33248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return "platforms/android-" + sdkVersion + "/data/res";
33348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
33448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
33548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	static boolean isLayoutDirectory( String path ) {
33648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return path.contains( File.separator + "layout" );
33748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
33848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
33948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	static boolean isDrawableDirectory( String path ) {
34048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return path.contains( File.separator + "drawable" );
34148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
34248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
34348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	static boolean isMenuDirectory( String path ) {
34448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return path.contains( File.separator + "menu" );
34548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
34648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
34748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	/*
34848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	 * For tests only...
34948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	 */
35048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	protected ResourceLoader( StringResourceLoader stringResourceLoader ) {
35148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		resourceExtractor = new ResourceExtractor();
35248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		this.stringResourceLoader = stringResourceLoader;
35348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		pluralResourceLoader = null;
35448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		viewLoader = null;
35548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		stringArrayResourceLoader = null;
35648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		attrResourceLoader = null;
35748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		colorResourceLoader = null;
35848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		drawableResourceLoader = null;
35948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		rawResourceLoader = null;
36048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		dimenResourceLoader = null;
36148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		integerResourceLoader = null;
36248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
36348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
36448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public static ResourceLoader getFrom( Context context ) {
36548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		ResourceLoader resourceLoader = shadowOf( context.getApplicationContext() ).getResourceLoader();
36648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		resourceLoader.init();
36748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return resourceLoader;
36848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
36948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
37048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public String getNameForId( int viewId ) {
37148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
37248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return resourceExtractor.getResourceName( viewId );
37348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
37448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
37548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public View inflateView( Context context, int resource, ViewGroup viewGroup ) {
37648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
37748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return viewLoader.inflateView( context, resource, viewGroup );
37848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
37948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
38048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public int getColorValue( int id ) {
38148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
38248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return colorResourceLoader.getValue( id );
38348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
38448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
38548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public String getStringValue( int id ) {
38648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
38748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return stringResourceLoader.getValue( id );
38848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
38948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
39048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public String getPluralStringValue( int id, int quantity ) {
39148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
39248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return pluralResourceLoader.getValue( id, quantity );
39348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
39448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
39548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public float getDimenValue( int id ) {
39648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
39748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return dimenResourceLoader.getValue( id );
39848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
39948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
40048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public int getIntegerValue( int id ) {
40148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
40248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return integerResourceLoader.getValue( id );
40348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
40448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
40548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public boolean isDrawableXml( int resourceId ) {
40648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
40748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return drawableResourceLoader.isXml( resourceId );
40848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
40948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
410aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu    public boolean isAnimatableXml( int resourceId ) {
411aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu        init();
412aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu        return drawableResourceLoader.isAnimationDrawable( resourceId );
413aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu    }
414aec1d0888fe04efd0cde7514e155870b18c41286Rick Kawala & Wei Wu
41548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public int[] getDrawableIds( int resourceId ) {
41648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
41748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return drawableResourceLoader.getDrawableIds( resourceId );
41848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
41948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
42048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public Drawable getXmlDrawable( int resourceId ) {
42148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return drawableResourceLoader.getXmlDrawable( resourceId );
42248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
42348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
42448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public Drawable getAnimDrawable( int resourceId ) {
42548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return getInnerRClassDrawable( resourceId, "$anim", AnimationDrawable.class );
42648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
42748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
42848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public Drawable getColorDrawable( int resourceId ) {
42948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return getInnerRClassDrawable( resourceId, "$color", ColorDrawable.class );
43048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
43148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
43248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	@SuppressWarnings("rawtypes")
433fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham	private Drawable getInnerRClassDrawable( int drawableResourceId, String suffix, Class returnClass ) {
43448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		ShadowContextWrapper shadowApp = Robolectric.shadowOf( Robolectric.application );
43548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		Class rClass = shadowApp.getResourceLoader().getLocalRClass();
43648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
43748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// Check to make sure there is actually an R Class, if not
43848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// return just a BitmapDrawable
43948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		if ( rClass == null ) {
44048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			return null;
44148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
44248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
44348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		// Load the Inner Class for interrogation
44448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		Class animClass = null;
44548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		try {
44648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			animClass = Class.forName( rClass.getCanonicalName() + suffix );
44748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		} catch ( ClassNotFoundException e ) {
448fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham			return null;
449fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham		}
45048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
451fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham		// Try to find the passed in resource ID
452fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham		try {
45348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			for ( Field field : animClass.getDeclaredFields() ) {
45448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				if ( field.getInt( animClass ) == drawableResourceId ) {
45548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao					return ( Drawable ) returnClass.newInstance();
45648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao				}
45748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao			}
45848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		} catch ( Exception e ) {
45948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		}
46048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
461fac8bbf7dfc7904540716be8649b2f5a5c9f6d15adriancowham		return null;
46248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
46348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
46448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public InputStream getRawValue( int id ) {
46548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
46648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return rawResourceLoader.getValue( id );
46748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
46848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
46948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public String[] getStringArrayValue( int id ) {
47048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
47148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return stringArrayResourceLoader.getArrayValue( id );
47248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
47348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
47448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public void inflateMenu( Context context, int resource, Menu root ) {
47548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
47648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		menuLoader.inflateMenu( context, resource, root );
47748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
47848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
47948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public PreferenceScreen inflatePreferences( Context context, int resourceId ) {
48048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
48148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return preferenceLoader.inflatePreferences( context, resourceId );
48248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
48348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
48448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public File getAssetsBase() {
48548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return assetsDir;
48648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
48748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
48848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	@SuppressWarnings("rawtypes")
48948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public Class getLocalRClass() {
49048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return rClass;
49148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
49248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
49348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public void setLocalRClass( Class clazz ) {
49448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		rClass = clazz;
49548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
49648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
49748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public ResourceExtractor getResourceExtractor() {
49848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return resourceExtractor;
49948f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
50048f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
50148f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public ViewLoader.ViewNode getLayoutViewNode( String layoutName ) {
50248f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		return viewLoader.viewNodesByLayoutName.get( layoutName );
50348f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
50448f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao
50548f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	public void setLayoutQualifierSearchPath( String... locations ) {
50648f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		init();
50748f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao		viewLoader.setLayoutQualifierSearchPath( locations );
50848f3d7b9a3f4a9f3b719782cae007edac11ed454Wenhui Yao	}
50947bd528af49de6d8459c8aeda60b88cc7a3c961fChristian Williams}
510