Loading core/java/android/preference/GenericInflater.java +29 −36 Original line number Diff line number Diff line Loading @@ -16,6 +16,10 @@ package android.preference; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; Loading @@ -27,21 +31,17 @@ import android.view.ContextThemeWrapper; import android.view.InflateException; import android.view.LayoutInflater; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; // TODO: fix generics /** * Generic XML inflater. This has been adapted from {@link LayoutInflater} and * quickly passed over to use generics. * * @hide * @param <T> The type of the items to inflate * @param <P> The type of parents (that is those items that contain other items). * @param T The type of the items to inflate * @param P The type of parents (that is those items that contain other items). * Must implement {@link GenericInflater.Parent} */ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { abstract class GenericInflater<T, P extends GenericInflater.Parent> { private final boolean DEBUG = false; protected final Context mContext; Loading @@ -52,11 +52,10 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { private final Object[] mConstructorArgs = new Object[2]; private static final Class<?>[] mConstructorSignature = new Class[] { private static final Class[] mConstructorSignature = new Class[] { Context.class, AttributeSet.class}; private static final HashMap<String, Constructor<?>> sConstructorMap = new HashMap<String, Constructor<?>>(); private static final HashMap sConstructorMap = new HashMap(); private String mDefaultPackage; Loading Loading @@ -135,7 +134,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * @return Returns a brand spanking new inflater object associated with * the given Context. */ public abstract GenericInflater<T,P> cloneInContext(Context newContext); public abstract GenericInflater cloneInContext(Context newContext); /** * Sets the default package that will be searched for classes to construct Loading Loading @@ -288,21 +287,22 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * attachToRoot is true, this is root; otherwise it is the root of * the inflated XML file. */ public T inflate(XmlPullParser parser, P root, boolean attachToRoot) { public T inflate(XmlPullParser parser, P root, boolean attachToRoot) { synchronized (mConstructorArgs) { final AttributeSet attrs = Xml.asAttributeSet(parser); mConstructorArgs[0] = mContext; P result = root; T result = (T) root; try { // Look for the root node. int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { // Do nothing while ((type = parser.next()) != parser.START_TAG && type != parser.END_DOCUMENT) { ; } if (type != XmlPullParser.START_TAG) { if (type != parser.START_TAG) { throw new InflateException(parser.getPositionDescription() + ": No start tag found!"); } Loading @@ -317,8 +317,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { T xmlRoot = createItemFromTag(parser, parser.getName(), attrs); // Unsafe cast. The current name is not guaranteed to be a P. result = onMergeRoots(root, attachToRoot, (P) xmlRoot); result = (T) onMergeRoots(root, attachToRoot, (P) xmlRoot); if (DEBUG) { System.out.println("-----> start inflating children"); Loading @@ -344,8 +343,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { throw ex; } // Unsafe cast return (T) result; return result; } } Loading @@ -364,17 +362,17 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * @param name The full name of the class to be instantiated. * @param attrs The XML attributes supplied for this instance. * * @return The newly instantiated item, or null. * @return The newly instantied item, or null. */ public final T createItem(String name, String prefix, AttributeSet attrs) throws ClassNotFoundException, InflateException { Constructor<?> constructor = sConstructorMap.get(name); Constructor constructor = (Constructor) sConstructorMap.get(name); try { if (null == constructor) { // Class not found in the cache, see if it's real, // and try to add it Class<?> clazz = mContext.getClassLoader().loadClass( Class clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name); constructor = clazz.getConstructor(mConstructorSignature); sConstructorMap.put(name, constructor); Loading @@ -382,8 +380,6 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { Object[] args = mConstructorArgs; args[1] = attrs; // This cast is NOT safe. The name class name is not guaranteed to be a // child class of T. return (T) constructor.newInstance(args); } catch (NoSuchMethodException e) { Loading Loading @@ -461,15 +457,15 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * Recursive method used to descend down the xml hierarchy and instantiate * items, instantiate their children, and then call onFinishInflate(). */ private void rInflate(XmlPullParser parser, P parent, final AttributeSet attrs) private void rInflate(XmlPullParser parser, T parent, final AttributeSet attrs) throws XmlPullParserException, IOException { final int depth = parser.getDepth(); int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { while (((type = parser.next()) != parser.END_TAG || parser.getDepth() > depth) && type != parser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { if (type != parser.START_TAG) { continue; } Loading @@ -489,13 +485,12 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { .println("Creating params from parent: " + parent); } parent.addItemFromInflater(item); ((P) parent).addItemFromInflater(item); if (DEBUG) { System.out.println("-----> start inflating children"); } // Unsafe cast rInflate(parser, (P)item, attrs); rInflate(parser, item, attrs); if (DEBUG) { System.out.println("-----> done inflating children"); } Loading @@ -513,10 +508,8 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * @param attrs An AttributeSet of attributes to apply to the item. * @return Whether you created a custom object (true), or whether this * inflater should proceed to create an item. * * @throws XmlPullParserException In case of parsing error. */ protected boolean onCreateCustomFromTag(XmlPullParser parser, P parent, protected boolean onCreateCustomFromTag(XmlPullParser parser, T parent, final AttributeSet attrs) throws XmlPullParserException { return false; } Loading core/java/android/preference/PreferenceInflater.java +5 −3 Original line number Diff line number Diff line Loading @@ -16,16 +16,18 @@ package android.preference; import java.io.IOException; import java.util.Map; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.app.AliasActivity; import android.content.Context; import android.content.Intent; import android.util.AttributeSet; import android.util.Log; import java.io.IOException; /** * The {@link PreferenceInflater} is used to inflate preference hierarchies from * XML files. Loading Loading @@ -61,7 +63,7 @@ class PreferenceInflater extends GenericInflater<Preference, PreferenceGroup> { } @Override protected boolean onCreateCustomFromTag(XmlPullParser parser, PreferenceGroup parentPreference, protected boolean onCreateCustomFromTag(XmlPullParser parser, Preference parentPreference, AttributeSet attrs) throws XmlPullParserException { final String tag = parser.getName(); Loading core/java/android/view/LayoutInflater.java +12 −19 Original line number Diff line number Diff line Loading @@ -16,15 +16,15 @@ package android.view; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.util.AttributeSet; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; Loading Loading @@ -71,11 +71,11 @@ public abstract class LayoutInflater { private final Object[] mConstructorArgs = new Object[2]; private static final Class<?>[] mConstructorSignature = new Class[] { private static final Class[] mConstructorSignature = new Class[] { Context.class, AttributeSet.class}; private static final HashMap<String, Constructor<? extends View>> sConstructorMap = new HashMap<String, Constructor<? extends View>>(); private static final HashMap<String, Constructor> sConstructorMap = new HashMap<String, Constructor>(); private HashMap<String, Boolean> mFilterMap; Loading Loading @@ -453,18 +453,18 @@ public abstract class LayoutInflater { * @param name The full name of the class to be instantiated. * @param attrs The XML attributes supplied for this instance. * * @return View The newly instantiated view, or null. * @return View The newly instantied view, or null. */ public final View createView(String name, String prefix, AttributeSet attrs) throws ClassNotFoundException, InflateException { Constructor<? extends View> constructor = sConstructorMap.get(name); Class<? extends View> clazz = null; Constructor constructor = sConstructorMap.get(name); Class clazz = null; try { if (constructor == null) { // Class not found in the cache, see if it's real, and try to add it clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name).asSubclass(View.class); prefix != null ? (prefix + name) : name); if (mFilter != null && clazz != null) { boolean allowed = mFilter.onLoadClass(clazz); Loading @@ -482,7 +482,7 @@ public abstract class LayoutInflater { if (allowedState == null) { // New class -- remember whether it is allowed clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name).asSubclass(View.class); prefix != null ? (prefix + name) : name); boolean allowed = clazz != null && mFilter.onLoadClass(clazz); mFilterMap.put(name, allowed); Loading @@ -497,7 +497,7 @@ public abstract class LayoutInflater { Object[] args = mConstructorArgs; args[1] = attrs; return constructor.newInstance(args); return (View) constructor.newInstance(args); } catch (NoSuchMethodException e) { InflateException ie = new InflateException(attrs.getPositionDescription() Loading @@ -506,13 +506,6 @@ public abstract class LayoutInflater { ie.initCause(e); throw ie; } catch (ClassCastException e) { // If loaded class is not a View subclass InflateException ie = new InflateException(attrs.getPositionDescription() + ": Class is not a View " + (prefix != null ? (prefix + name) : name)); ie.initCause(e); throw ie; } catch (ClassNotFoundException e) { // If loadClass fails, we should propagate the exception. throw e; Loading Loading
core/java/android/preference/GenericInflater.java +29 −36 Original line number Diff line number Diff line Loading @@ -16,6 +16,10 @@ package android.preference; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; Loading @@ -27,21 +31,17 @@ import android.view.ContextThemeWrapper; import android.view.InflateException; import android.view.LayoutInflater; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; // TODO: fix generics /** * Generic XML inflater. This has been adapted from {@link LayoutInflater} and * quickly passed over to use generics. * * @hide * @param <T> The type of the items to inflate * @param <P> The type of parents (that is those items that contain other items). * @param T The type of the items to inflate * @param P The type of parents (that is those items that contain other items). * Must implement {@link GenericInflater.Parent} */ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { abstract class GenericInflater<T, P extends GenericInflater.Parent> { private final boolean DEBUG = false; protected final Context mContext; Loading @@ -52,11 +52,10 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { private final Object[] mConstructorArgs = new Object[2]; private static final Class<?>[] mConstructorSignature = new Class[] { private static final Class[] mConstructorSignature = new Class[] { Context.class, AttributeSet.class}; private static final HashMap<String, Constructor<?>> sConstructorMap = new HashMap<String, Constructor<?>>(); private static final HashMap sConstructorMap = new HashMap(); private String mDefaultPackage; Loading Loading @@ -135,7 +134,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * @return Returns a brand spanking new inflater object associated with * the given Context. */ public abstract GenericInflater<T,P> cloneInContext(Context newContext); public abstract GenericInflater cloneInContext(Context newContext); /** * Sets the default package that will be searched for classes to construct Loading Loading @@ -288,21 +287,22 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * attachToRoot is true, this is root; otherwise it is the root of * the inflated XML file. */ public T inflate(XmlPullParser parser, P root, boolean attachToRoot) { public T inflate(XmlPullParser parser, P root, boolean attachToRoot) { synchronized (mConstructorArgs) { final AttributeSet attrs = Xml.asAttributeSet(parser); mConstructorArgs[0] = mContext; P result = root; T result = (T) root; try { // Look for the root node. int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { // Do nothing while ((type = parser.next()) != parser.START_TAG && type != parser.END_DOCUMENT) { ; } if (type != XmlPullParser.START_TAG) { if (type != parser.START_TAG) { throw new InflateException(parser.getPositionDescription() + ": No start tag found!"); } Loading @@ -317,8 +317,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { T xmlRoot = createItemFromTag(parser, parser.getName(), attrs); // Unsafe cast. The current name is not guaranteed to be a P. result = onMergeRoots(root, attachToRoot, (P) xmlRoot); result = (T) onMergeRoots(root, attachToRoot, (P) xmlRoot); if (DEBUG) { System.out.println("-----> start inflating children"); Loading @@ -344,8 +343,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { throw ex; } // Unsafe cast return (T) result; return result; } } Loading @@ -364,17 +362,17 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * @param name The full name of the class to be instantiated. * @param attrs The XML attributes supplied for this instance. * * @return The newly instantiated item, or null. * @return The newly instantied item, or null. */ public final T createItem(String name, String prefix, AttributeSet attrs) throws ClassNotFoundException, InflateException { Constructor<?> constructor = sConstructorMap.get(name); Constructor constructor = (Constructor) sConstructorMap.get(name); try { if (null == constructor) { // Class not found in the cache, see if it's real, // and try to add it Class<?> clazz = mContext.getClassLoader().loadClass( Class clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name); constructor = clazz.getConstructor(mConstructorSignature); sConstructorMap.put(name, constructor); Loading @@ -382,8 +380,6 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { Object[] args = mConstructorArgs; args[1] = attrs; // This cast is NOT safe. The name class name is not guaranteed to be a // child class of T. return (T) constructor.newInstance(args); } catch (NoSuchMethodException e) { Loading Loading @@ -461,15 +457,15 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * Recursive method used to descend down the xml hierarchy and instantiate * items, instantiate their children, and then call onFinishInflate(). */ private void rInflate(XmlPullParser parser, P parent, final AttributeSet attrs) private void rInflate(XmlPullParser parser, T parent, final AttributeSet attrs) throws XmlPullParserException, IOException { final int depth = parser.getDepth(); int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { while (((type = parser.next()) != parser.END_TAG || parser.getDepth() > depth) && type != parser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { if (type != parser.START_TAG) { continue; } Loading @@ -489,13 +485,12 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { .println("Creating params from parent: " + parent); } parent.addItemFromInflater(item); ((P) parent).addItemFromInflater(item); if (DEBUG) { System.out.println("-----> start inflating children"); } // Unsafe cast rInflate(parser, (P)item, attrs); rInflate(parser, item, attrs); if (DEBUG) { System.out.println("-----> done inflating children"); } Loading @@ -513,10 +508,8 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent<T>> { * @param attrs An AttributeSet of attributes to apply to the item. * @return Whether you created a custom object (true), or whether this * inflater should proceed to create an item. * * @throws XmlPullParserException In case of parsing error. */ protected boolean onCreateCustomFromTag(XmlPullParser parser, P parent, protected boolean onCreateCustomFromTag(XmlPullParser parser, T parent, final AttributeSet attrs) throws XmlPullParserException { return false; } Loading
core/java/android/preference/PreferenceInflater.java +5 −3 Original line number Diff line number Diff line Loading @@ -16,16 +16,18 @@ package android.preference; import java.io.IOException; import java.util.Map; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.app.AliasActivity; import android.content.Context; import android.content.Intent; import android.util.AttributeSet; import android.util.Log; import java.io.IOException; /** * The {@link PreferenceInflater} is used to inflate preference hierarchies from * XML files. Loading Loading @@ -61,7 +63,7 @@ class PreferenceInflater extends GenericInflater<Preference, PreferenceGroup> { } @Override protected boolean onCreateCustomFromTag(XmlPullParser parser, PreferenceGroup parentPreference, protected boolean onCreateCustomFromTag(XmlPullParser parser, Preference parentPreference, AttributeSet attrs) throws XmlPullParserException { final String tag = parser.getName(); Loading
core/java/android/view/LayoutInflater.java +12 −19 Original line number Diff line number Diff line Loading @@ -16,15 +16,15 @@ package android.view; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.util.AttributeSet; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.HashMap; Loading Loading @@ -71,11 +71,11 @@ public abstract class LayoutInflater { private final Object[] mConstructorArgs = new Object[2]; private static final Class<?>[] mConstructorSignature = new Class[] { private static final Class[] mConstructorSignature = new Class[] { Context.class, AttributeSet.class}; private static final HashMap<String, Constructor<? extends View>> sConstructorMap = new HashMap<String, Constructor<? extends View>>(); private static final HashMap<String, Constructor> sConstructorMap = new HashMap<String, Constructor>(); private HashMap<String, Boolean> mFilterMap; Loading Loading @@ -453,18 +453,18 @@ public abstract class LayoutInflater { * @param name The full name of the class to be instantiated. * @param attrs The XML attributes supplied for this instance. * * @return View The newly instantiated view, or null. * @return View The newly instantied view, or null. */ public final View createView(String name, String prefix, AttributeSet attrs) throws ClassNotFoundException, InflateException { Constructor<? extends View> constructor = sConstructorMap.get(name); Class<? extends View> clazz = null; Constructor constructor = sConstructorMap.get(name); Class clazz = null; try { if (constructor == null) { // Class not found in the cache, see if it's real, and try to add it clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name).asSubclass(View.class); prefix != null ? (prefix + name) : name); if (mFilter != null && clazz != null) { boolean allowed = mFilter.onLoadClass(clazz); Loading @@ -482,7 +482,7 @@ public abstract class LayoutInflater { if (allowedState == null) { // New class -- remember whether it is allowed clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name).asSubclass(View.class); prefix != null ? (prefix + name) : name); boolean allowed = clazz != null && mFilter.onLoadClass(clazz); mFilterMap.put(name, allowed); Loading @@ -497,7 +497,7 @@ public abstract class LayoutInflater { Object[] args = mConstructorArgs; args[1] = attrs; return constructor.newInstance(args); return (View) constructor.newInstance(args); } catch (NoSuchMethodException e) { InflateException ie = new InflateException(attrs.getPositionDescription() Loading @@ -506,13 +506,6 @@ public abstract class LayoutInflater { ie.initCause(e); throw ie; } catch (ClassCastException e) { // If loaded class is not a View subclass InflateException ie = new InflateException(attrs.getPositionDescription() + ": Class is not a View " + (prefix != null ? (prefix + name) : name)); ie.initCause(e); throw ie; } catch (ClassNotFoundException e) { // If loadClass fails, we should propagate the exception. throw e; Loading