WidgetClassLoaderpublic final class WidgetClassLoader extends Object implements IAndroidClassLoaderParser for the text file containing the list of widgets, layouts and layout params.
The file is a straight text file containing one class per line.
Each line is in the following format
[code][class name] [super class name] [super class name]...
where code is a single letter (W for widget, L for layout, P for layout params), and class names
are the fully qualified name of the classes. |
Fields Summary |
---|
private BufferedReader | mReader | private final Map | mMapOutput map of FQCN => descriptor on all classes | private final Map | mWidgetMapOutput map of FQCN => descriptor on View classes | private final Map | mLayoutMapOutput map of FQCN => descriptor on ViewGroup classes | private final Map | mLayoutParamsMapOutput map of FQCN => descriptor on LayoutParams classes | private String | mOsFilePathFile path of the source text file |
Constructors Summary |
---|
WidgetClassLoader(String osFilePath)Creates a loader with a given file path.
mOsFilePath = osFilePath;
mReader = new BufferedReader(new FileReader(osFilePath));
|
Methods Summary |
---|
public java.util.HashMap | findClassesDerivingFrom(java.lang.String rootPackage, java.lang.String[] superClasses)Finds and loads all classes that derive from a given set of super classes.
HashMap<String, ArrayList<IClassDescriptor>> map =
new HashMap<String, ArrayList<IClassDescriptor>>();
ArrayList<IClassDescriptor> list = new ArrayList<IClassDescriptor>();
list.addAll(mWidgetMap.values());
map.put(AndroidConstants.CLASS_VIEW, list);
list = new ArrayList<IClassDescriptor>();
list.addAll(mLayoutMap.values());
map.put(AndroidConstants.CLASS_VIEWGROUP, list);
list = new ArrayList<IClassDescriptor>();
list.addAll(mLayoutParamsMap.values());
map.put(AndroidConstants.CLASS_VIEWGROUP_LAYOUTPARAMS, list);
return map;
| public IClassDescriptor | getClass(java.lang.String className)Returns a {@link IAndroidClassLoader.IClassDescriptor} by its fully-qualified name.
return mMap.get(className);
| private java.lang.String | getEnclosedName(java.lang.String fqcn)
int index = fqcn.lastIndexOf('.");
return fqcn.substring(0, index);
| public java.lang.String | getSource()
return mOsFilePath;
| boolean | parseWidgetList(org.eclipse.core.runtime.IProgressMonitor monitor)Parses the text file and return true if the file was successfully parsed.
try {
String line;
while ((line = mReader.readLine()) != null) {
if (line.length() > 0) {
char prefix = line.charAt(0);
String[] classes = null;
ClassDescriptor clazz = null;
switch (prefix) {
case 'W":
classes = line.substring(1).split(" ");
clazz = processClass(classes, 0, null /* map */);
if (clazz != null) {
clazz.setInstantiable(true);
mWidgetMap.put(classes[0], clazz);
}
break;
case 'L":
classes = line.substring(1).split(" ");
clazz = processClass(classes, 0, null /* map */);
if (clazz != null) {
clazz.setInstantiable(true);
mLayoutMap.put(classes[0], clazz);
}
break;
case 'P":
classes = line.substring(1).split(" ");
clazz = processClass(classes, 0, mLayoutParamsMap);
if (clazz != null) {
clazz.setInstantiable(true);
}
break;
case '#":
// comment, do nothing
break;
default:
throw new IllegalArgumentException();
}
}
}
// reconciliate the layout and their layout params
postProcess();
return true;
} catch (IOException e) {
} finally {
try {
mReader.close();
} catch (IOException e) {
}
}
return false;
| private void | postProcess()Goes through the layout params and look for the enclosed class. If the layout params
has no known enclosed type it is dropped.
Collection<ClassDescriptor> params = mLayoutParamsMap.values();
for (ClassDescriptor param : params) {
String fqcn = param.getCanonicalName();
// get the enclosed name.
String enclosed = getEnclosedName(fqcn);
// look for a match in the layouts. We don't use the layout map as it only contains the
// end classes, but in this case we also need to process the layout params for the base
// layout classes.
ClassDescriptor enclosingType = mMap.get(enclosed);
if (enclosingType != null) {
param.setEnclosingClass(enclosingType);
// remove the class from the map, and put it back with the fixed name
mMap.remove(fqcn);
mMap.put(param.getCanonicalName(), param);
}
}
| private com.android.ide.eclipse.adt.sdk.WidgetClassLoader$ClassDescriptor | processClass(java.lang.String[] classes, int index, java.util.Map map)Parses a View class and adds a ViewClassInfo for it in mWidgetMap.
It calls itself recursively to handle super classes which are also Views.
if (index >= classes.length) {
return null;
}
String fqcn = classes[index];
if ("java.lang.Object".equals(fqcn)) { //$NON-NLS-1$
return null;
}
// check if the ViewInfoClass has not yet been created.
if (mMap.containsKey(fqcn)) {
return mMap.get(fqcn);
}
// create the custom class.
ClassDescriptor clazz = new ClassDescriptor(fqcn);
mMap.put(fqcn, clazz);
if (map != null) {
map.put(fqcn, clazz);
}
// get the super class
ClassDescriptor superClass = processClass(classes, index+1, map);
if (superClass != null) {
clazz.setSuperClass(superClass);
}
return clazz;
|
|