• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.xtremelabs.robolectric.res;
2 
3 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
4 
5 import com.xtremelabs.robolectric.Robolectric;
6 import com.xtremelabs.robolectric.shadows.ShadowContextWrapper;
7 import com.xtremelabs.robolectric.util.I18nException;
8 import com.xtremelabs.robolectric.util.PropertiesHelper;
9 
10 import android.R;
11 import android.content.Context;
12 import android.graphics.drawable.AnimationDrawable;
13 import android.graphics.drawable.ColorDrawable;
14 import android.graphics.drawable.Drawable;
15 import android.preference.PreferenceScreen;
16 import android.text.TextUtils;
17 import android.view.Menu;
18 import android.view.View;
19 import android.view.ViewGroup;
20 
21 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.FileFilter;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.lang.reflect.Field;
29 import java.util.HashSet;
30 import java.util.Properties;
31 import java.util.Set;
32 
33 public class ResourceLoader {
34 	private static final FileFilter MENU_DIR_FILE_FILTER = new FileFilter() {
35 		@Override
36 		public boolean accept( File file ) {
37 			return isMenuDirectory( file.getPath() );
38 		}
39 	};
40 	private static final FileFilter LAYOUT_DIR_FILE_FILTER = new FileFilter() {
41 		@Override
42 		public boolean accept( File file ) {
43 			return isLayoutDirectory( file.getPath() );
44 		}
45 	};
46 	private static final FileFilter DRAWABLE_DIR_FILE_FILTER = new FileFilter() {
47 		@Override
48 		public boolean accept( File file ) {
49 			return isDrawableDirectory( file.getPath() );
50 		}
51 	};
52 
53 	private File resourceDir;
54 	private File assetsDir;
55 	private int sdkVersion;
56 	private Class rClass;
57 
58 	private final ResourceExtractor resourceExtractor;
59 	private ViewLoader viewLoader;
60 	private MenuLoader menuLoader;
61 	private PreferenceLoader preferenceLoader;
62 	private final StringResourceLoader stringResourceLoader;
63 	private final PluralResourceLoader pluralResourceLoader;
64 	private final StringArrayResourceLoader stringArrayResourceLoader;
65 	private final AttrResourceLoader attrResourceLoader;
66 	private final ColorResourceLoader colorResourceLoader;
67 	private final DrawableResourceLoader drawableResourceLoader;
68 	private final RawResourceLoader rawResourceLoader;
69 	private final DimenResourceLoader dimenResourceLoader;
70 	private final IntegerResourceLoader integerResourceLoader;
71 	private boolean isInitialized = false;
72 	private boolean strictI18n = false;
73 	private String locale="";
74 
75 	private final Set<Integer> ninePatchDrawableIds = new HashSet<Integer>();
76 
ResourceLoader( int sdkVersion, Class rClass, File resourceDir, File assetsDir )77 	public ResourceLoader(  int sdkVersion, Class rClass, File resourceDir, File assetsDir ) throws Exception {
78 		this( sdkVersion, rClass, resourceDir, assetsDir, "");
79 	}
80 
ResourceLoader( int sdkVersion, Class rClass, File resourceDir, File assetsDir, String locale )81 	public ResourceLoader( int sdkVersion, Class rClass, File resourceDir, File assetsDir, String locale ) throws Exception {
82 		this.sdkVersion = sdkVersion;
83 		this.assetsDir = assetsDir;
84 		this.rClass = rClass;
85 		this.locale = locale;
86 
87 		resourceExtractor = new ResourceExtractor();
88 		if ( rClass != null ) {
89 		  resourceExtractor.addLocalRClass( rClass );
90 		}
91 		resourceExtractor.addSystemRClass( R.class );
92 
93 		stringResourceLoader = new StringResourceLoader( resourceExtractor );
94 		pluralResourceLoader = new PluralResourceLoader( resourceExtractor, stringResourceLoader );
95 		stringArrayResourceLoader = new StringArrayResourceLoader( resourceExtractor, stringResourceLoader );
96 		colorResourceLoader = new ColorResourceLoader( resourceExtractor );
97 		attrResourceLoader = new AttrResourceLoader( resourceExtractor );
98 		drawableResourceLoader = new DrawableResourceLoader( resourceExtractor, resourceDir );
99 		rawResourceLoader = new RawResourceLoader( resourceExtractor, resourceDir );
100 		dimenResourceLoader = new DimenResourceLoader( resourceExtractor );
101 		integerResourceLoader = new IntegerResourceLoader( resourceExtractor );
102 
103 		this.resourceDir = resourceDir;
104 	}
105 
setStrictI18n( boolean strict )106 	public void setStrictI18n( boolean strict ) {
107 		this.strictI18n = strict;
108 		if ( viewLoader != null ) {
109 			viewLoader.setStrictI18n( strict );
110 		}
111 		if ( menuLoader != null ) {
112 			menuLoader.setStrictI18n( strict );
113 		}
114 		if ( preferenceLoader != null ) {
115 			preferenceLoader.setStrictI18n( strict );
116 		}
117 	}
118 
getStrictI18n()119 	public boolean getStrictI18n() {
120 		return strictI18n;
121 	}
122 
init()123 	private void init() {
124 		if ( isInitialized ) {
125 			return;
126 		}
127 
128 		try {
129 			if ( resourceDir != null ) {
130 				viewLoader = new ViewLoader( resourceExtractor, attrResourceLoader );
131 				menuLoader = new MenuLoader( resourceExtractor, attrResourceLoader );
132 				preferenceLoader = new PreferenceLoader( resourceExtractor );
133 
134 				viewLoader.setStrictI18n( strictI18n );
135 				menuLoader.setStrictI18n( strictI18n );
136 				preferenceLoader.setStrictI18n( strictI18n );
137 
138 				File systemResourceDir = getSystemResourceDir( getPathToAndroidResources() );
139 				File localValueResourceDir = getValueResourceDir( resourceDir );
140 				File systemValueResourceDir = getValueResourceDir( systemResourceDir );
141 				File preferenceDir = getPreferenceResourceDir( resourceDir );
142 
143 				loadStringResources( localValueResourceDir, systemValueResourceDir );
144 				loadPluralsResources( localValueResourceDir, systemValueResourceDir );
145 				loadValueResources( localValueResourceDir, systemValueResourceDir );
146 				loadDimenResources( localValueResourceDir, systemValueResourceDir );
147 				loadIntegerResource( localValueResourceDir, systemValueResourceDir );
148 				loadViewResources( systemResourceDir, resourceDir );
149 				loadMenuResources( resourceDir );
150 				loadDrawableResources( resourceDir );
151 				loadPreferenceResources( preferenceDir );
152 
153 				listNinePatchResources(ninePatchDrawableIds, resourceDir);
154 			} else {
155 				viewLoader = null;
156 				menuLoader = null;
157 				preferenceLoader = null;
158 			}
159 		} catch ( I18nException e ) {
160 			throw e;
161 		} catch ( Exception e ) {
162 			throw new RuntimeException( e );
163 		}
164 		isInitialized = true;
165 	}
166 
getSystemResourceDir( String pathToAndroidResources )167 	private File getSystemResourceDir( String pathToAndroidResources ) {
168 		return pathToAndroidResources != null ? new File( pathToAndroidResources ) : null;
169 	}
170 
loadStringResources( File localResourceDir, File systemValueResourceDir )171 	private void loadStringResources( File localResourceDir, File systemValueResourceDir ) throws Exception {
172 		DocumentLoader stringResourceDocumentLoader = new DocumentLoader( this.stringResourceLoader );
173 		loadValueResourcesFromDirs( stringResourceDocumentLoader, localResourceDir, systemValueResourceDir );
174 	}
175 
loadPluralsResources( File localResourceDir, File systemValueResourceDir )176 	private void loadPluralsResources( File localResourceDir, File systemValueResourceDir ) throws Exception {
177 		DocumentLoader stringResourceDocumentLoader = new DocumentLoader( this.pluralResourceLoader );
178 		loadValueResourcesFromDirs( stringResourceDocumentLoader, localResourceDir, systemValueResourceDir );
179 	}
180 
loadValueResources( File localResourceDir, File systemValueResourceDir )181 	private void loadValueResources( File localResourceDir, File systemValueResourceDir ) throws Exception {
182 		DocumentLoader valueResourceLoader = new DocumentLoader( stringArrayResourceLoader, colorResourceLoader,
183 				attrResourceLoader );
184 		loadValueResourcesFromDirs( valueResourceLoader, localResourceDir, systemValueResourceDir );
185 	}
186 
loadDimenResources( File localResourceDir, File systemValueResourceDir )187 	private void loadDimenResources( File localResourceDir, File systemValueResourceDir ) throws Exception {
188 		DocumentLoader dimenResourceDocumentLoader = new DocumentLoader( this.dimenResourceLoader );
189 		loadValueResourcesFromDirs( dimenResourceDocumentLoader, localResourceDir, systemValueResourceDir );
190 	}
191 
loadIntegerResource( File localResourceDir, File systemValueResourceDir )192 	private void loadIntegerResource( File localResourceDir, File systemValueResourceDir ) throws Exception {
193 		DocumentLoader integerResourceDocumentLoader = new DocumentLoader( this.integerResourceLoader );
194 		loadValueResourcesFromDirs( integerResourceDocumentLoader, localResourceDir, systemValueResourceDir );
195 	}
196 
loadViewResources( File systemResourceDir, File xmlResourceDir )197 	private void loadViewResources( File systemResourceDir, File xmlResourceDir ) throws Exception {
198 		DocumentLoader viewDocumentLoader = new DocumentLoader( viewLoader );
199 		loadLayoutResourceXmlSubDirs( viewDocumentLoader, xmlResourceDir, false );
200 		loadLayoutResourceXmlSubDirs( viewDocumentLoader, systemResourceDir, true );
201 	}
202 
loadMenuResources( File xmlResourceDir )203 	private void loadMenuResources( File xmlResourceDir ) throws Exception {
204 		DocumentLoader menuDocumentLoader = new DocumentLoader( menuLoader );
205 		loadMenuResourceXmlDirs( menuDocumentLoader, xmlResourceDir );
206 	}
207 
loadDrawableResources( File xmlResourceDir )208 	private void loadDrawableResources( File xmlResourceDir ) throws Exception {
209 		DocumentLoader drawableDocumentLoader = new DocumentLoader( drawableResourceLoader );
210 		loadDrawableResourceXmlDirs( drawableDocumentLoader, xmlResourceDir );
211 	}
212 
loadPreferenceResources( File xmlResourceDir )213 	private void loadPreferenceResources( File xmlResourceDir ) throws Exception {
214 		if ( xmlResourceDir.exists() ) {
215 			DocumentLoader preferenceDocumentLoader = new DocumentLoader( preferenceLoader );
216 			preferenceDocumentLoader.loadResourceXmlDir( xmlResourceDir );
217 		}
218 	}
219 
loadLayoutResourceXmlSubDirs( DocumentLoader layoutDocumentLoader, File xmlResourceDir, boolean isSystem )220 	private void loadLayoutResourceXmlSubDirs( DocumentLoader layoutDocumentLoader, File xmlResourceDir, boolean isSystem )
221 			throws Exception {
222 		if ( xmlResourceDir != null ) {
223 			layoutDocumentLoader.loadResourceXmlDirs( isSystem, xmlResourceDir.listFiles( LAYOUT_DIR_FILE_FILTER ) );
224 		}
225 	}
226 
loadMenuResourceXmlDirs( DocumentLoader menuDocumentLoader, File xmlResourceDir )227 	private void loadMenuResourceXmlDirs( DocumentLoader menuDocumentLoader, File xmlResourceDir ) throws Exception {
228 		if ( xmlResourceDir != null ) {
229 			menuDocumentLoader.loadResourceXmlDirs( xmlResourceDir.listFiles( MENU_DIR_FILE_FILTER ) );
230 		}
231 	}
232 
loadDrawableResourceXmlDirs( DocumentLoader drawableResourceLoader, File xmlResourceDir )233 	private void loadDrawableResourceXmlDirs( DocumentLoader drawableResourceLoader, File xmlResourceDir ) throws Exception {
234 		if ( xmlResourceDir != null ) {
235 			drawableResourceLoader.loadResourceXmlDirs( xmlResourceDir.listFiles( DRAWABLE_DIR_FILE_FILTER ) );
236 		}
237 	}
238 
loadValueResourcesFromDirs( DocumentLoader documentLoader, File localValueResourceDir, File systemValueResourceDir )239 	private void loadValueResourcesFromDirs( DocumentLoader documentLoader, File localValueResourceDir,
240 			File systemValueResourceDir ) throws Exception {
241 		loadValueResourcesFromDir( documentLoader, localValueResourceDir );
242 		loadSystemResourceXmlDir( documentLoader, systemValueResourceDir );
243 	}
244 
loadValueResourcesFromDir( DocumentLoader documentloader, File xmlResourceDir )245 	private void loadValueResourcesFromDir( DocumentLoader documentloader, File xmlResourceDir ) throws Exception {
246 		if ( xmlResourceDir != null ) {
247 			documentloader.loadResourceXmlDir( xmlResourceDir );
248 		}
249 	}
250 
loadSystemResourceXmlDir( DocumentLoader documentLoader, File stringResourceDir )251 	private void loadSystemResourceXmlDir( DocumentLoader documentLoader, File stringResourceDir ) throws Exception {
252 		if ( stringResourceDir != null ) {
253 			documentLoader.loadSystemResourceXmlDir( stringResourceDir );
254 		}
255 	}
256 
getValueResourceDir( File xmlResourceDir )257 	private File getValueResourceDir( File xmlResourceDir ) {
258 		String valuesDir = "values";
259 		if( !TextUtils.isEmpty( locale ) ){
260 			valuesDir += "-"+ locale;
261 		}
262 		File result = ( xmlResourceDir != null ) ? new File( xmlResourceDir, valuesDir ) : null;
263 		if( result != null && !result.exists() ){
264 			throw new RuntimeException("Couldn't find value resource directory: " + result.getAbsolutePath() );
265 		}
266 		return result;
267 	}
268 
getPreferenceResourceDir( File xmlResourceDir )269 	private File getPreferenceResourceDir( File xmlResourceDir ) {
270 		return xmlResourceDir != null ? new File( xmlResourceDir, "xml" ) : null;
271 	}
272 
getPathToAndroidResources()273 	private String getPathToAndroidResources() {
274 		String resFolder = getAndroidResourcePathFromLocalProperties();
275 		if (resFolder == null) {
276 			resFolder = getAndroidResourcePathFromSystemEnvironment();
277 			if (resFolder == null) {
278 				resFolder = getAndroidResourcePathFromSystemProperty();
279 				if (resFolder == null) {
280 					resFolder = getAndroidResourcePathByExecingWhichAndroid();
281 				}
282 			}
283 		}
284 
285 		// Go through last 5 sdk versions looking for resource folders.
286 		if (resFolder != null) {
287 			for (int i = sdkVersion; i >= sdkVersion - 5 && i >= 4; i--) {
288 				File resourcePath = new File(resFolder, getAndroidResourceSubPath(i));
289 				if (resourcePath.exists()) {
290 					return resourcePath.getAbsolutePath();
291 				} else {
292 					System.out.println("WARNING: Unable to find Android resources at: " +
293 							resourcePath.toString() + " continuing.");
294 				}
295 			}
296 		} else {
297 			System.out.println("WARNING: Unable to find path to Android SDK");
298 		}
299 
300 		return null;
301 	}
302 
getAndroidResourcePathFromLocalProperties()303 	private String getAndroidResourcePathFromLocalProperties() {
304 		// Hand tested
305 		// This is the path most often taken by IntelliJ
306 		File rootDir = resourceDir.getParentFile();
307 		String localPropertiesFileName = "local.properties";
308 		File localPropertiesFile = new File( rootDir, localPropertiesFileName );
309 		if ( !localPropertiesFile.exists() ) {
310 			localPropertiesFile = new File( localPropertiesFileName );
311 		}
312 		if ( localPropertiesFile.exists() ) {
313 			Properties localProperties = new Properties();
314 			try {
315 				localProperties.load( new FileInputStream( localPropertiesFile ) );
316 				PropertiesHelper.doSubstitutions( localProperties );
317 				return localProperties.getProperty( "sdk.dir" );
318 			} catch ( IOException e ) {
319 				// fine, we'll try something else
320 			}
321 		}
322 		return null;
323 	}
324 
getAndroidResourcePathFromSystemEnvironment()325 	private String getAndroidResourcePathFromSystemEnvironment() {
326 		// Hand tested
327 		return System.getenv().get( "ANDROID_HOME" );
328 	}
329 
getAndroidResourcePathFromSystemProperty()330 	private String getAndroidResourcePathFromSystemProperty() {
331 		// this is used by the android-maven-plugin
332 		return System.getProperty( "android.sdk.path" );
333 	}
334 
getAndroidResourcePathByExecingWhichAndroid()335 	private String getAndroidResourcePathByExecingWhichAndroid() {
336 		// Hand tested
337 		// Should always work from the command line. Often fails in IDEs because
338 		// they don't pass the full PATH in the environment
339 		try {
340 			Process process = Runtime.getRuntime().exec( new String[] { "which", "android" } );
341 			String sdkPath = new BufferedReader( new InputStreamReader( process.getInputStream() ) ).readLine();
342 			if ( sdkPath != null && sdkPath.endsWith( "tools/android" ) ) {
343 			    return sdkPath.substring(0, sdkPath.indexOf( "tools/android"));
344 			}
345 		} catch ( IOException e ) {
346 			// fine we'll try something else
347 		}
348 		return null;
349 	}
350 
getAndroidResourceSubPath(int version)351 	private static String getAndroidResourceSubPath(int version) {
352 		return "platforms/android-" + version + "/data/res";
353 	}
354 
isLayoutDirectory( String path )355 	static boolean isLayoutDirectory( String path ) {
356 		return path.contains( File.separator + "layout" );
357 	}
358 
isDrawableDirectory( String path )359 	static boolean isDrawableDirectory( String path ) {
360 		return path.contains( File.separator + "drawable" );
361 	}
362 
isMenuDirectory( String path )363 	static boolean isMenuDirectory( String path ) {
364 		return path.contains( File.separator + "menu" );
365 	}
366 
367 	/*
368 	 * For tests only...
369 	 */
ResourceLoader( StringResourceLoader stringResourceLoader )370 	protected ResourceLoader( StringResourceLoader stringResourceLoader ) {
371 		resourceExtractor = new ResourceExtractor();
372 		this.stringResourceLoader = stringResourceLoader;
373 		pluralResourceLoader = null;
374 		viewLoader = null;
375 		stringArrayResourceLoader = null;
376 		attrResourceLoader = null;
377 		colorResourceLoader = null;
378 		drawableResourceLoader = null;
379 		rawResourceLoader = null;
380 		dimenResourceLoader = null;
381 		integerResourceLoader = null;
382 	}
383 
getFrom( Context context )384 	public static ResourceLoader getFrom( Context context ) {
385 		ResourceLoader resourceLoader = shadowOf( context.getApplicationContext() ).getResourceLoader();
386 		resourceLoader.init();
387 		return resourceLoader;
388 	}
389 
getNameForId( int viewId )390 	public String getNameForId( int viewId ) {
391 		init();
392 		return resourceExtractor.getResourceName( viewId );
393 	}
394 
inflateView( Context context, int resource, ViewGroup viewGroup )395 	public View inflateView( Context context, int resource, ViewGroup viewGroup ) {
396 		init();
397 		return viewLoader.inflateView( context, resource, viewGroup );
398 	}
399 
getColorValue( int id )400 	public int getColorValue( int id ) {
401 		init();
402 		return colorResourceLoader.getValue( id );
403 	}
404 
getStringValue( int id )405 	public String getStringValue( int id ) {
406 		init();
407 		return stringResourceLoader.getValue( id );
408 	}
409 
getPluralStringValue( int id, int quantity )410 	public String getPluralStringValue( int id, int quantity ) {
411 		init();
412 		return pluralResourceLoader.getValue( id, quantity );
413 	}
414 
getDimenValue( int id )415 	public float getDimenValue( int id ) {
416 		init();
417 		return dimenResourceLoader.getValue( id );
418 	}
419 
getIntegerValue( int id )420 	public int getIntegerValue( int id ) {
421 		init();
422 		return integerResourceLoader.getValue( id );
423 	}
424 
isDrawableXml( int resourceId )425 	public boolean isDrawableXml( int resourceId ) {
426 		init();
427 		return drawableResourceLoader.isXml( resourceId );
428 	}
429 
isAnimatableXml( int resourceId )430     public boolean isAnimatableXml( int resourceId ) {
431         init();
432         return drawableResourceLoader.isAnimationDrawable( resourceId );
433     }
434 
getDrawableIds( int resourceId )435 	public int[] getDrawableIds( int resourceId ) {
436 		init();
437 		return drawableResourceLoader.getDrawableIds( resourceId );
438 	}
439 
getXmlDrawable( int resourceId )440 	public Drawable getXmlDrawable( int resourceId ) {
441 		return drawableResourceLoader.getXmlDrawable( resourceId );
442 	}
443 
getAnimDrawable( int resourceId )444 	public Drawable getAnimDrawable( int resourceId ) {
445 		return getInnerRClassDrawable( resourceId, "$anim", AnimationDrawable.class );
446 	}
447 
getColorDrawable( int resourceId )448 	public Drawable getColorDrawable( int resourceId ) {
449 		return getInnerRClassDrawable( resourceId, "$color", ColorDrawable.class );
450 	}
451 
452 	@SuppressWarnings("rawtypes")
getInnerRClassDrawable( int drawableResourceId, String suffix, Class returnClass )453 	private Drawable getInnerRClassDrawable( int drawableResourceId, String suffix, Class returnClass ) {
454 		ShadowContextWrapper shadowApp = Robolectric.shadowOf( Robolectric.application );
455 		Class rClass = shadowApp.getResourceLoader().getLocalRClass();
456 
457 		// Check to make sure there is actually an R Class, if not
458 		// return just a BitmapDrawable
459 		if ( rClass == null ) {
460 			return null;
461 		}
462 
463 		// Load the Inner Class for interrogation
464 		Class animClass = null;
465 		try {
466 			animClass = Class.forName( rClass.getCanonicalName() + suffix );
467 		} catch ( ClassNotFoundException e ) {
468 			return null;
469 		}
470 
471 		// Try to find the passed in resource ID
472 		try {
473 			for ( Field field : animClass.getDeclaredFields() ) {
474 				if ( field.getInt( animClass ) == drawableResourceId ) {
475 					return ( Drawable ) returnClass.newInstance();
476 				}
477 			}
478 		} catch ( Exception e ) {
479 		}
480 
481 		return null;
482 	}
483 
isNinePatchDrawable(int drawableResourceId)484 	public boolean isNinePatchDrawable(int drawableResourceId) {
485 		return ninePatchDrawableIds.contains(drawableResourceId);
486 	}
487 
488 	/**
489 	 * Returns a collection of resource IDs for all nine-patch drawables
490 	 * in the project.
491 	 *
492 	 * @param resourceIds
493 	 * @param dir
494 	 */
listNinePatchResources(Set<Integer> resourceIds, File dir)495 	private void listNinePatchResources(Set<Integer> resourceIds, File dir) {
496 		File[] files = dir.listFiles();
497 		if (files != null) {
498 			for (File f : files) {
499 				if (f.isDirectory() && isDrawableDirectory(f.getPath())) {
500 					listNinePatchResources(resourceIds, f);
501 				} else {
502 					String name = f.getName();
503 					if (name.endsWith(".9.png")) {
504 						String[] tokens = name.split("\\.9\\.png$");
505 						resourceIds.add(resourceExtractor.getResourceId("@drawable/" + tokens[0]));
506 					}
507 				}
508 			}
509 		}
510 	}
511 
getRawValue( int id )512 	public InputStream getRawValue( int id ) {
513 		init();
514 		return rawResourceLoader.getValue( id );
515 	}
516 
getStringArrayValue( int id )517 	public String[] getStringArrayValue( int id ) {
518 		init();
519 		return stringArrayResourceLoader.getArrayValue( id );
520 	}
521 
inflateMenu( Context context, int resource, Menu root )522 	public void inflateMenu( Context context, int resource, Menu root ) {
523 		init();
524 		menuLoader.inflateMenu( context, resource, root );
525 	}
526 
inflatePreferences( Context context, int resourceId )527 	public PreferenceScreen inflatePreferences( Context context, int resourceId ) {
528 		init();
529 		return preferenceLoader.inflatePreferences( context, resourceId );
530 	}
531 
getAssetsBase()532 	public File getAssetsBase() {
533 		return assetsDir;
534 	}
535 
536 	@SuppressWarnings("rawtypes")
getLocalRClass()537 	public Class getLocalRClass() {
538 		return rClass;
539 	}
540 
setLocalRClass( Class clazz )541 	public void setLocalRClass( Class clazz ) {
542 		rClass = clazz;
543 	}
544 
getResourceExtractor()545 	public ResourceExtractor getResourceExtractor() {
546 		return resourceExtractor;
547 	}
548 
getLayoutViewNode( String layoutName )549 	public ViewLoader.ViewNode getLayoutViewNode( String layoutName ) {
550 		return viewLoader.viewNodesByLayoutName.get( layoutName );
551 	}
552 
setLayoutQualifierSearchPath( String... locations )553 	public void setLayoutQualifierSearchPath( String... locations ) {
554 		init();
555 		viewLoader.setLayoutQualifierSearchPath( locations );
556 	}
557 }
558