• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
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.ide.eclipse.adt.internal.sdk;
18 
19 import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
20 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors;
21 import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
22 import com.android.ide.eclipse.adt.internal.editors.menu.descriptors.MenuDescriptors;
23 import com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors;
24 import com.android.ide.eclipse.adt.internal.editors.xml.descriptors.XmlDescriptors;
25 import com.android.ide.eclipse.adt.internal.resources.IResourceRepository;
26 import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
27 import com.android.layoutlib.api.ILayoutBridge;
28 import com.android.sdklib.IAndroidTarget;
29 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
30 
31 import java.util.ArrayList;
32 import java.util.Hashtable;
33 import java.util.Map;
34 
35 /**
36  * This class contains the data of an Android Target as loaded from the SDK.
37  */
38 public class AndroidTargetData {
39 
40     public final static int DESCRIPTOR_MANIFEST = 1;
41     public final static int DESCRIPTOR_LAYOUT = 2;
42     public final static int DESCRIPTOR_MENU = 3;
43     public final static int DESCRIPTOR_XML = 4;
44     public final static int DESCRIPTOR_RESOURCES = 5;
45     public final static int DESCRIPTOR_SEARCHABLE = 6;
46     public final static int DESCRIPTOR_PREFERENCES = 7;
47     public final static int DESCRIPTOR_APPWIDGET_PROVIDER = 8;
48 
49     public final static class LayoutBridge {
50         /** Link to the layout bridge */
51         public ILayoutBridge bridge;
52 
53         public LoadStatus status = LoadStatus.LOADING;
54 
55         public ClassLoader classLoader;
56 
57         public int apiLevel;
58     }
59 
60     private final IAndroidTarget mTarget;
61 
62     private DexWrapper mDexWrapper;
63 
64     /**
65      * mAttributeValues is a map { key => list [ values ] }.
66      * The key for the map is "(element-xml-name,attribute-namespace:attribute-xml-local-name)".
67      * The attribute namespace prefix must be:
68      * - "android" for AndroidConstants.NS_RESOURCES
69      * - "xmlns" for the XMLNS URI.
70      *
71      * This is used for attributes that do not have a unique name, but still need to be populated
72      * with values in the UI. Uniquely named attributes have their values in {@link #mEnumValueMap}.
73      */
74     private Hashtable<String, String[]> mAttributeValues = new Hashtable<String, String[]>();
75 
76     private IResourceRepository mSystemResourceRepository;
77 
78     private AndroidManifestDescriptors mManifestDescriptors;
79     private LayoutDescriptors mLayoutDescriptors;
80     private MenuDescriptors mMenuDescriptors;
81     private XmlDescriptors mXmlDescriptors;
82 
83     private Map<String, Map<String, Integer>> mEnumValueMap;
84 
85     private ProjectResources mFrameworkResources;
86     private LayoutBridge mLayoutBridge;
87 
88     private boolean mLayoutBridgeInit = false;
89 
AndroidTargetData(IAndroidTarget androidTarget)90     AndroidTargetData(IAndroidTarget androidTarget) {
91         mTarget = androidTarget;
92     }
93 
setDexWrapper(DexWrapper wrapper)94     void setDexWrapper(DexWrapper wrapper) {
95         mDexWrapper = wrapper;
96     }
97 
98     /**
99      * Creates an AndroidTargetData object.
100      * @param platformLibraries
101      * @param optionalLibraries
102      */
setExtraData(IResourceRepository systemResourceRepository, AndroidManifestDescriptors manifestDescriptors, LayoutDescriptors layoutDescriptors, MenuDescriptors menuDescriptors, XmlDescriptors xmlDescriptors, Map<String, Map<String, Integer>> enumValueMap, String[] permissionValues, String[] activityIntentActionValues, String[] broadcastIntentActionValues, String[] serviceIntentActionValues, String[] intentCategoryValues, String[] platformLibraries, IOptionalLibrary[] optionalLibraries, ProjectResources resources, LayoutBridge layoutBridge)103     void setExtraData(IResourceRepository systemResourceRepository,
104             AndroidManifestDescriptors manifestDescriptors,
105             LayoutDescriptors layoutDescriptors,
106             MenuDescriptors menuDescriptors,
107             XmlDescriptors xmlDescriptors,
108             Map<String, Map<String, Integer>> enumValueMap,
109             String[] permissionValues,
110             String[] activityIntentActionValues,
111             String[] broadcastIntentActionValues,
112             String[] serviceIntentActionValues,
113             String[] intentCategoryValues,
114             String[] platformLibraries,
115             IOptionalLibrary[] optionalLibraries,
116             ProjectResources resources,
117             LayoutBridge layoutBridge) {
118 
119         mSystemResourceRepository = systemResourceRepository;
120         mManifestDescriptors = manifestDescriptors;
121         mLayoutDescriptors = layoutDescriptors;
122         mMenuDescriptors = menuDescriptors;
123         mXmlDescriptors = xmlDescriptors;
124         mEnumValueMap = enumValueMap;
125         mFrameworkResources = resources;
126         mLayoutBridge = layoutBridge;
127 
128         setPermissions(permissionValues);
129         setIntentFilterActionsAndCategories(activityIntentActionValues, broadcastIntentActionValues,
130                 serviceIntentActionValues, intentCategoryValues);
131         setOptionalLibraries(platformLibraries, optionalLibraries);
132     }
133 
getDexWrapper()134     public DexWrapper getDexWrapper() {
135         return mDexWrapper;
136     }
137 
getSystemResources()138     public IResourceRepository getSystemResources() {
139         return mSystemResourceRepository;
140     }
141 
142     /**
143      * Returns an {@link IDescriptorProvider} from a given Id.
144      * The Id can be one of {@link #DESCRIPTOR_MANIFEST}, {@link #DESCRIPTOR_LAYOUT},
145      * {@link #DESCRIPTOR_MENU}, or {@link #DESCRIPTOR_XML}.
146      * All other values will throw an {@link IllegalArgumentException}.
147      */
getDescriptorProvider(int descriptorId)148     public IDescriptorProvider getDescriptorProvider(int descriptorId) {
149         switch (descriptorId) {
150             case DESCRIPTOR_MANIFEST:
151                 return mManifestDescriptors;
152             case DESCRIPTOR_LAYOUT:
153                 return mLayoutDescriptors;
154             case DESCRIPTOR_MENU:
155                 return mMenuDescriptors;
156             case DESCRIPTOR_XML:
157                 return mXmlDescriptors;
158             case DESCRIPTOR_RESOURCES:
159                 // FIXME: since it's hard-coded the Resources Descriptors are not platform dependent.
160                 return ResourcesDescriptors.getInstance();
161             case DESCRIPTOR_PREFERENCES:
162                 return mXmlDescriptors.getPreferencesProvider();
163             case DESCRIPTOR_APPWIDGET_PROVIDER:
164                 return mXmlDescriptors.getAppWidgetProvider();
165             case DESCRIPTOR_SEARCHABLE:
166                 return mXmlDescriptors.getSearchableProvider();
167             default :
168                  throw new IllegalArgumentException();
169         }
170     }
171 
172     /**
173      * Returns the manifest descriptors.
174      */
getManifestDescriptors()175     public AndroidManifestDescriptors getManifestDescriptors() {
176         return mManifestDescriptors;
177     }
178 
179     /**
180      * Returns the layout Descriptors.
181      */
getLayoutDescriptors()182     public LayoutDescriptors getLayoutDescriptors() {
183         return mLayoutDescriptors;
184     }
185 
186     /**
187      * Returns the menu descriptors.
188      */
getMenuDescriptors()189     public MenuDescriptors getMenuDescriptors() {
190         return mMenuDescriptors;
191     }
192 
193     /**
194      * Returns the XML descriptors
195      */
getXmlDescriptors()196     public XmlDescriptors getXmlDescriptors() {
197         return mXmlDescriptors;
198     }
199 
200     /**
201      * Returns this list of possible values for an XML attribute.
202      * <p/>This should only be called for attributes for which possible values depend on the
203      * parent element node.
204      * <p/>For attributes that have the same values no matter the parent node, use
205      * {@link #getEnumValueMap()}.
206      * @param elementName the name of the element containing the attribute.
207      * @param attributeName the name of the attribute
208      * @return an array of String with the possible values, or <code>null</code> if no values were
209      * found.
210      */
getAttributeValues(String elementName, String attributeName)211     public String[] getAttributeValues(String elementName, String attributeName) {
212         String key = String.format("(%1$s,%2$s)", elementName, attributeName); //$NON-NLS-1$
213         return mAttributeValues.get(key);
214     }
215 
216     /**
217      * Returns this list of possible values for an XML attribute.
218      * <p/>This should only be called for attributes for which possible values depend on the
219      * parent and great-grand-parent element node.
220      * <p/>The typical example of this is for the 'name' attribute under
221      * activity/intent-filter/action
222      * <p/>For attributes that have the same values no matter the parent node, use
223      * {@link #getEnumValueMap()}.
224      * @param elementName the name of the element containing the attribute.
225      * @param attributeName the name of the attribute
226      * @param greatGrandParentElementName the great-grand-parent node.
227      * @return an array of String with the possible values, or <code>null</code> if no values were
228      * found.
229      */
getAttributeValues(String elementName, String attributeName, String greatGrandParentElementName)230     public String[] getAttributeValues(String elementName, String attributeName,
231             String greatGrandParentElementName) {
232         if (greatGrandParentElementName != null) {
233             String key = String.format("(%1$s,%2$s,%3$s)", //$NON-NLS-1$
234                     greatGrandParentElementName, elementName, attributeName);
235             String[] values = mAttributeValues.get(key);
236             if (values != null) {
237                 return values;
238             }
239         }
240 
241         return getAttributeValues(elementName, attributeName);
242     }
243 
244     /**
245      * Returns the enum values map.
246      * <p/>The map defines the possible values for XML attributes. The key is the attribute name
247      * and the value is a map of (string, integer) in which the key (string) is the name of
248      * the value, and the Integer is the numerical value in the compiled binary XML files.
249      */
getEnumValueMap()250     public Map<String, Map<String, Integer>> getEnumValueMap() {
251         return mEnumValueMap;
252     }
253 
254     /**
255      * Returns the {@link ProjectResources} containing the Framework Resources.
256      */
getFrameworkResources()257     public ProjectResources getFrameworkResources() {
258         return mFrameworkResources;
259     }
260 
261     /**
262      * Returns a {@link LayoutBridge} object possibly containing a {@link ILayoutBridge} object.
263      * <p/>If {@link LayoutBridge#bridge} is <code>null</code>, {@link LayoutBridge#status} will
264      * contain the reason (either {@link LoadStatus#LOADING} or {@link LoadStatus#FAILED}).
265      * <p/>Valid {@link ILayoutBridge} objects are always initialized before being returned.
266      */
getLayoutBridge()267     public synchronized LayoutBridge getLayoutBridge() {
268         if (mLayoutBridgeInit == false && mLayoutBridge.bridge != null) {
269             mLayoutBridge.bridge.init(mTarget.getPath(IAndroidTarget.FONTS),
270                     getEnumValueMap());
271             mLayoutBridgeInit = true;
272         }
273         return mLayoutBridge;
274     }
275 
276     /**
277      * Sets the permission values
278      * @param permissionValues the list of permissions
279      */
setPermissions(String[] permissionValues)280     private void setPermissions(String[] permissionValues) {
281         setValues("(uses-permission,android:name)", permissionValues);   //$NON-NLS-1$
282         setValues("(application,android:permission)", permissionValues); //$NON-NLS-1$
283         setValues("(activity,android:permission)", permissionValues);    //$NON-NLS-1$
284         setValues("(receiver,android:permission)", permissionValues);    //$NON-NLS-1$
285         setValues("(service,android:permission)", permissionValues);     //$NON-NLS-1$
286         setValues("(provider,android:permission)", permissionValues);    //$NON-NLS-1$
287     }
288 
setIntentFilterActionsAndCategories(String[] activityIntentActions, String[] broadcastIntentActions, String[] serviceIntentActions, String[] intentCategoryValues)289     private void setIntentFilterActionsAndCategories(String[] activityIntentActions,
290             String[] broadcastIntentActions, String[] serviceIntentActions,
291             String[] intentCategoryValues) {
292         setValues("(activity,action,android:name)", activityIntentActions);  //$NON-NLS-1$
293         setValues("(receiver,action,android:name)", broadcastIntentActions); //$NON-NLS-1$
294         setValues("(service,action,android:name)", serviceIntentActions);    //$NON-NLS-1$
295         setValues("(category,android:name)", intentCategoryValues);          //$NON-NLS-1$
296     }
297 
setOptionalLibraries(String[] platformLibraries, IOptionalLibrary[] optionalLibraries)298     private void setOptionalLibraries(String[] platformLibraries,
299             IOptionalLibrary[] optionalLibraries) {
300 
301         ArrayList<String> libs = new ArrayList<String>();
302 
303         if (platformLibraries != null) {
304             for (String name : platformLibraries) {
305                 libs.add(name);
306             }
307         }
308 
309         if (optionalLibraries != null) {
310             for (int i = 0; i < optionalLibraries.length; i++) {
311                 libs.add(optionalLibraries[i].getName());
312             }
313         }
314         setValues("(uses-library,android:name)",  libs.toArray(new String[libs.size()]));
315     }
316 
317     /**
318      * Sets a (name, values) pair in the hash map.
319      * <p/>
320      * If the name is already present in the map, it is first removed.
321      * @param name the name associated with the values.
322      * @param values The values to add.
323      */
setValues(String name, String[] values)324     private void setValues(String name, String[] values) {
325         mAttributeValues.remove(name);
326         mAttributeValues.put(name, values);
327     }
328 }
329