1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.camera;
18 
19 import org.xmlpull.v1.XmlPullParser;
20 import org.xmlpull.v1.XmlPullParserException;
21 
22 import java.io.IOException;
23 import java.lang.reflect.Constructor;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 
27 import android.content.Context;
28 import android.util.AttributeSet;
29 import android.util.Xml;
30 import android.view.InflateException;
31 
32 /**
33  * Inflate <code>CameraPreference</code> from XML resource.
34  */
35 public class PreferenceInflater {
36     private static final String PACKAGE_NAME =
37             PreferenceInflater.class.getPackage().getName();
38 
39     private static final Class<?>[] CTOR_SIGNATURE =
40             new Class[] {Context.class, AttributeSet.class};
41     private static final HashMap<String, Constructor<?>> sConstructorMap =
42             new HashMap<String, Constructor<?>>();
43 
44     private Context mContext;
45 
PreferenceInflater(Context context)46     public PreferenceInflater(Context context) {
47         mContext = context;
48     }
49 
inflate(int resId)50     public CameraPreference inflate(int resId) {
51         return inflate(mContext.getResources().getXml(resId));
52     }
53 
newPreference(String tagName, Object[] args)54     private CameraPreference newPreference(String tagName, Object[] args) {
55         String name = PACKAGE_NAME + "." + tagName;
56         Constructor<?> constructor = sConstructorMap.get(name);
57         try {
58             if (constructor == null) {
59                 // Class not found in the cache, see if it's real, and try to
60                 // add it
61                 Class<?> clazz = mContext.getClassLoader().loadClass(name);
62                 constructor = clazz.getConstructor(CTOR_SIGNATURE);
63                 sConstructorMap.put(name, constructor);
64             }
65             return (CameraPreference) constructor.newInstance(args);
66         } catch (NoSuchMethodException e) {
67             throw new InflateException("Error inflating class " + name, e);
68         } catch (ClassNotFoundException e) {
69             throw new InflateException("No such class: " + name, e);
70         } catch (Exception e) {
71             throw new InflateException("While create instance of" + name, e);
72         }
73     }
74 
inflate(XmlPullParser parser)75     private CameraPreference inflate(XmlPullParser parser) {
76 
77         AttributeSet attrs = Xml.asAttributeSet(parser);
78         ArrayList<CameraPreference> list = new ArrayList<CameraPreference>();
79         Object args[] = new Object[]{mContext, attrs};
80 
81         try {
82             for (int type = parser.next();
83                     type != XmlPullParser.END_DOCUMENT; type = parser.next()) {
84                 if (type != XmlPullParser.START_TAG) continue;
85                 CameraPreference pref = newPreference(parser.getName(), args);
86 
87                 int depth = parser.getDepth();
88                 if (depth > list.size()) {
89                     list.add(pref);
90                 } else {
91                     list.set(depth - 1, pref);
92                 }
93                 if (depth > 1) {
94                     ((PreferenceGroup) list.get(depth - 2)).addChild(pref);
95                 }
96             }
97 
98             if (list.size() == 0) {
99                 throw new InflateException("No root element found");
100             }
101             return list.get(0);
102         } catch (XmlPullParserException e) {
103             throw new InflateException(e);
104         } catch (IOException e) {
105             throw new InflateException(parser.getPositionDescription(), e);
106         }
107     }
108 }
109