/* * Copyright (c) 2004-2009 XMLVM --- An XML-based Programming Language * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 675 Mass * Ave, Cambridge, MA 02139, USA. * * For more information, visit the XMLVM Home Page at http://www.xmlvm.org */ package android.content.res; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.Locale; import org.xmlvm.iphone.NSBundle; import org.xmlvm.iphone.NSData; import org.xmlvm.iphone.UIImage; import android.content.Context; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.internal.ActivityManager; import android.internal.Assert; import android.internal.ResourceParser; import android.util.DisplayMetrics; import android.util.Log; public class Resources { /** The name of the directory holding the application's resources. */ private static final String RES_DIR = "res"; /** A map holding the mapping from IDs to variable names. */ private Map<Integer, String> idToNameMap = new HashMap<Integer, String>(); /** A map holding the mapping from variable names to IDs. */ private Map<String, Integer> nameToIdMap = new HashMap<String, Integer>(); /** A map holding the mapping from resourceId to Drawable. */ private Map<Integer, Drawable> drawableMap = new HashMap<Integer, Drawable>(); /** * A map holding the mapping from resourceId to NSData (representing the * content of the XML layout file). */ private static Map<Integer, NSData> layoutMap = new HashMap<Integer, NSData>(); private static Map<Integer, String> stringMap; private static Map<Integer, String[]> stringArrayMap; private Context context; public Resources(Context context) { this.context = context; init(); }; public Drawable getDrawable(int resourceId) { Drawable d = drawableMap.get(new Integer(resourceId)); if (d == null) { String fileName = getFileNamePath(findResourceNameById(resourceId)); UIImage image = UIImage.imageWithContentsOfFile(fileName + ".png"); if (image != null) { d = BitmapDrawable.xmlvmCreateWithImage(image); drawableMap.put(new Integer(resourceId), d); } else { d = ResourceParser.parseDrawable(context, fileName); drawableMap.put(new Integer(resourceId), d); } } return d; } public NSData getLayout(int resourceId) { NSData theFile = layoutMap.get(new Integer(resourceId)); if (theFile == null) { String resourceName = getResourceName(findResourceNameById(resourceId)); String resourceDir = getResourceDirectory(findResourceNameById(resourceId)); String filePath = NSBundle.mainBundle().pathForResource(resourceName, "xml", resourceDir); theFile = NSData.dataWithContentsOfFile(filePath); layoutMap.put(new Integer(resourceId), theFile); } return theFile; } public int getIdentifier(String name, String defType, String defPackage) { String str = name; int i; // Remove package i = str.indexOf(':'); if (i != -1) { str = str.substring(i + 1); } // Prepend resource type if not specified if (str.indexOf('/') == -1 && defType != null) { str = defType + "/" + str; } return findResourceIdByName(str); } public String getResourceEntryName(int resourceId) { String str = findResourceNameById(resourceId); return str == null ? null : str.substring(str.indexOf('/')); } public String getResourcePackageName(int resourceId) { return ActivityManager.getApplicationPackageName(); } public String getResourceTypeName(int resourceId) { String str = findResourceNameById(resourceId); return str == null ? null : str.substring(0, str.indexOf('/')); } public String getResourceName(int resourceId) { String str = findResourceNameById(resourceId); return str == null ? null : ActivityManager.getApplicationPackageName() + ':' + str; } private String findResourceNameById(int resourceId) { String name = idToNameMap.get(new Integer(resourceId)); return name != null ? name : ""; } private int findResourceIdByName(String resourceName) { Integer i = nameToIdMap.get(resourceName); return i != null ? i.intValue() : -1; } private void initResources(String resourceClass) { try { String activityPackageName = ActivityManager.getApplicationPackageName(); String rClassName = activityPackageName + ".R$" + resourceClass; Class<?> rClazz = Class.forName(rClassName); Field[] fields = rClazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { String fullFieldName = resourceClass + "/" + fields[i].getName(); idToNameMap.put(new Integer(fields[i].getInt(rClazz)), fullFieldName); nameToIdMap.put(fullFieldName, new Integer(fields[i].getInt(rClazz))); } } catch (Throwable t) { Log.i("Resources", "Unable to resolve resources for " + ActivityManager.getApplicationPackageName() + ": " + resourceClass); } } private void init() { idToNameMap = new HashMap<Integer, String>(); nameToIdMap = new HashMap<String, Integer>(); initResources("attr"); initResources("drawable"); initResources("id"); initResources("layout"); initResources("string"); initResources("array"); } private String getFileNamePath(String filePath) { return RES_DIR + "/" + filePath; } private String getResourceName(String filePath) { int i = filePath.lastIndexOf('/'); return i >= 0 ? filePath.substring(i + 1) : filePath; } private String getResourceDirectory(String filePath) { String fileName = RES_DIR + "/" + filePath; int i = fileName.lastIndexOf('/'); return i >= 0 ? fileName.substring(0, i) : null; } /** * @param id * @return */ public String getString(int id) { if (stringMap == null) { String path = getValuesDir() + "/" + "strings"; stringMap = ResourceParser.parseStrings(context, path, nameToIdMap); } return stringMap.get(new Integer(id)); } public String[] getTextArray(int id) { if (stringArrayMap == null) { String path = getValuesDir(); stringArrayMap = ResourceParser.parseStringArrays(context, path, nameToIdMap); } return stringArrayMap.get(new Integer(id)); } public String getText(int id) { return getString(id); } private String getValuesDir() { String locale = Locale.getDefault().toString(); locale = locale.replaceAll("-", "_"); String path = RES_DIR + "/values-" + locale; String resP = NSBundle.mainBundle().pathForResource("strings", "xml", path); if (resP == null) { String[] p = locale.split("_"); // just use language if (p.length >= 2) { path = RES_DIR + "/values-" + p[0]; resP = NSBundle.mainBundle().pathForResource("strings", "xml", path); } } if (resP == null) { path = RES_DIR + "/values"; // default values, should always exist } return path; } public DisplayMetrics getDisplayMetrics() { Assert.NOT_IMPLEMENTED(); return null; } public Configuration getConfiguration() { Assert.NOT_IMPLEMENTED(); return null; } }