• 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.common.rendering.LayoutLibrary;
20 import com.android.ide.common.rendering.api.LayoutLog;
21 import com.android.ide.common.resources.ResourceRepository;
22 import com.android.ide.common.sdk.LoadStatus;
23 import com.android.ide.eclipse.adt.AdtPlugin;
24 import com.android.ide.eclipse.adt.internal.editors.animator.AnimDescriptors;
25 import com.android.ide.eclipse.adt.internal.editors.animator.AnimatorDescriptors;
26 import com.android.ide.eclipse.adt.internal.editors.color.ColorDescriptors;
27 import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
28 import com.android.ide.eclipse.adt.internal.editors.drawable.DrawableDescriptors;
29 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors;
30 import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
31 import com.android.ide.eclipse.adt.internal.editors.menu.descriptors.MenuDescriptors;
32 import com.android.ide.eclipse.adt.internal.editors.otherxml.descriptors.OtherXmlDescriptors;
33 import com.android.ide.eclipse.adt.internal.editors.values.descriptors.ValuesDescriptors;
34 import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
35 import com.android.sdklib.IAndroidTarget;
36 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
37 
38 import org.eclipse.core.runtime.IStatus;
39 
40 import java.io.File;
41 import java.util.ArrayList;
42 import java.util.Hashtable;
43 import java.util.Map;
44 
45 /**
46  * This class contains the data of an Android Target as loaded from the SDK.
47  */
48 public class AndroidTargetData {
49 
50     public final static int DESCRIPTOR_MANIFEST = 1;
51     public final static int DESCRIPTOR_LAYOUT = 2;
52     public final static int DESCRIPTOR_MENU = 3;
53     public final static int DESCRIPTOR_OTHER_XML = 4;
54     public final static int DESCRIPTOR_RESOURCES = 5;
55     public final static int DESCRIPTOR_SEARCHABLE = 6;
56     public final static int DESCRIPTOR_PREFERENCES = 7;
57     public final static int DESCRIPTOR_APPWIDGET_PROVIDER = 8;
58     public final static int DESCRIPTOR_DRAWABLE = 9;
59     public final static int DESCRIPTOR_ANIMATOR = 10;
60     public final static int DESCRIPTOR_ANIM = 11;
61     public final static int DESCRIPTOR_COLOR = 12;
62 
63     private final IAndroidTarget mTarget;
64 
65     /**
66      * mAttributeValues is a map { key => list [ values ] }.
67      * The key for the map is "(element-xml-name,attribute-namespace:attribute-xml-local-name)".
68      * The attribute namespace prefix must be:
69      * - "android" for AndroidConstants.NS_RESOURCES
70      * - "xmlns" for the XMLNS URI.
71      *
72      * This is used for attributes that do not have a unique name, but still need to be populated
73      * with values in the UI. Uniquely named attributes have their values in {@link #mEnumValueMap}.
74      */
75     private Hashtable<String, String[]> mAttributeValues = new Hashtable<String, String[]>();
76 
77     private AndroidManifestDescriptors mManifestDescriptors;
78     private DrawableDescriptors mDrawableDescriptors;
79     private AnimatorDescriptors mAnimatorDescriptors;
80     private AnimDescriptors mAnimDescriptors;
81     private ColorDescriptors mColorDescriptors;
82     private LayoutDescriptors mLayoutDescriptors;
83     private MenuDescriptors mMenuDescriptors;
84     private OtherXmlDescriptors mOtherXmlDescriptors;
85 
86     private Map<String, Map<String, Integer>> mEnumValueMap;
87 
88     private ResourceRepository mFrameworkResources;
89     private LayoutLibrary mLayoutLibrary;
90 
91     private boolean mLayoutBridgeInit = false;
92 
AndroidTargetData(IAndroidTarget androidTarget)93     AndroidTargetData(IAndroidTarget androidTarget) {
94         mTarget = androidTarget;
95     }
96 
97     /**
98      * Creates an AndroidTargetData object.
99      */
setExtraData( AndroidManifestDescriptors manifestDescriptors, LayoutDescriptors layoutDescriptors, MenuDescriptors menuDescriptors, OtherXmlDescriptors otherXmlDescriptors, DrawableDescriptors drawableDescriptors, AnimatorDescriptors animatorDescriptors, AnimDescriptors animDescriptors, ColorDescriptors colorDescriptors, Map<String, Map<String, Integer>> enumValueMap, String[] permissionValues, String[] activityIntentActionValues, String[] broadcastIntentActionValues, String[] serviceIntentActionValues, String[] intentCategoryValues, String[] platformLibraries, IOptionalLibrary[] optionalLibraries, ResourceRepository frameworkResources, LayoutLibrary layoutLibrary)100     void setExtraData(
101             AndroidManifestDescriptors manifestDescriptors,
102             LayoutDescriptors layoutDescriptors,
103             MenuDescriptors menuDescriptors,
104             OtherXmlDescriptors otherXmlDescriptors,
105             DrawableDescriptors drawableDescriptors,
106             AnimatorDescriptors animatorDescriptors,
107             AnimDescriptors animDescriptors,
108             ColorDescriptors colorDescriptors,
109             Map<String, Map<String, Integer>> enumValueMap,
110             String[] permissionValues,
111             String[] activityIntentActionValues,
112             String[] broadcastIntentActionValues,
113             String[] serviceIntentActionValues,
114             String[] intentCategoryValues,
115             String[] platformLibraries,
116             IOptionalLibrary[] optionalLibraries,
117             ResourceRepository frameworkResources,
118             LayoutLibrary layoutLibrary) {
119 
120         mManifestDescriptors = manifestDescriptors;
121         mDrawableDescriptors = drawableDescriptors;
122         mAnimatorDescriptors = animatorDescriptors;
123         mAnimDescriptors = animDescriptors;
124         mColorDescriptors = colorDescriptors;
125         mLayoutDescriptors = layoutDescriptors;
126         mMenuDescriptors = menuDescriptors;
127         mOtherXmlDescriptors = otherXmlDescriptors;
128         mEnumValueMap = enumValueMap;
129         mFrameworkResources = frameworkResources;
130         mLayoutLibrary = layoutLibrary;
131 
132         setPermissions(permissionValues);
133         setIntentFilterActionsAndCategories(activityIntentActionValues, broadcastIntentActionValues,
134                 serviceIntentActionValues, intentCategoryValues);
135         setOptionalLibraries(platformLibraries, optionalLibraries);
136     }
137 
138     /**
139      * Returns an {@link IDescriptorProvider} from a given Id.
140      * The Id can be one of {@link #DESCRIPTOR_MANIFEST}, {@link #DESCRIPTOR_LAYOUT},
141      * {@link #DESCRIPTOR_MENU}, or {@link #DESCRIPTOR_OTHER_XML}.
142      * All other values will throw an {@link IllegalArgumentException}.
143      */
getDescriptorProvider(int descriptorId)144     public IDescriptorProvider getDescriptorProvider(int descriptorId) {
145         switch (descriptorId) {
146             case DESCRIPTOR_MANIFEST:
147                 return mManifestDescriptors;
148             case DESCRIPTOR_LAYOUT:
149                 return mLayoutDescriptors;
150             case DESCRIPTOR_MENU:
151                 return mMenuDescriptors;
152             case DESCRIPTOR_OTHER_XML:
153                 return mOtherXmlDescriptors;
154             case DESCRIPTOR_RESOURCES:
155                 // FIXME: since it's hard-coded the Resources Descriptors are not platform dependent.
156                 return ValuesDescriptors.getInstance();
157             case DESCRIPTOR_PREFERENCES:
158                 return mOtherXmlDescriptors.getPreferencesProvider();
159             case DESCRIPTOR_APPWIDGET_PROVIDER:
160                 return mOtherXmlDescriptors.getAppWidgetProvider();
161             case DESCRIPTOR_SEARCHABLE:
162                 return mOtherXmlDescriptors.getSearchableProvider();
163             case DESCRIPTOR_DRAWABLE:
164                 return mDrawableDescriptors;
165             case DESCRIPTOR_ANIMATOR:
166                 return mAnimatorDescriptors;
167             case DESCRIPTOR_ANIM:
168                 return mAnimDescriptors;
169             case DESCRIPTOR_COLOR:
170                 return mColorDescriptors;
171             default :
172                  throw new IllegalArgumentException();
173         }
174     }
175 
176     /**
177      * Returns the manifest descriptors.
178      */
getManifestDescriptors()179     public AndroidManifestDescriptors getManifestDescriptors() {
180         return mManifestDescriptors;
181     }
182 
183     /**
184      * Returns the drawable descriptors
185      */
getDrawableDescriptors()186     public DrawableDescriptors getDrawableDescriptors() {
187         return mDrawableDescriptors;
188     }
189 
190     /**
191      * Returns the animation descriptors
192      */
getAnimDescriptors()193     public AnimDescriptors getAnimDescriptors() {
194         return mAnimDescriptors;
195     }
196 
197     /**
198      * Returns the color descriptors
199      */
getColorDescriptors()200     public ColorDescriptors getColorDescriptors() {
201         return mColorDescriptors;
202     }
203 
204     /**
205      * Returns the animator descriptors
206      */
getAnimatorDescriptors()207     public AnimatorDescriptors getAnimatorDescriptors() {
208         return mAnimatorDescriptors;
209     }
210 
211     /**
212      * Returns the layout Descriptors.
213      */
getLayoutDescriptors()214     public LayoutDescriptors getLayoutDescriptors() {
215         return mLayoutDescriptors;
216     }
217 
218     /**
219      * Returns the menu descriptors.
220      */
getMenuDescriptors()221     public MenuDescriptors getMenuDescriptors() {
222         return mMenuDescriptors;
223     }
224 
225     /**
226      * Returns the XML descriptors
227      */
getXmlDescriptors()228     public OtherXmlDescriptors getXmlDescriptors() {
229         return mOtherXmlDescriptors;
230     }
231 
232     /**
233      * Returns this list of possible values for an XML attribute.
234      * <p/>This should only be called for attributes for which possible values depend on the
235      * parent element node.
236      * <p/>For attributes that have the same values no matter the parent node, use
237      * {@link #getEnumValueMap()}.
238      * @param elementName the name of the element containing the attribute.
239      * @param attributeName the name of the attribute
240      * @return an array of String with the possible values, or <code>null</code> if no values were
241      * found.
242      */
getAttributeValues(String elementName, String attributeName)243     public String[] getAttributeValues(String elementName, String attributeName) {
244         String key = String.format("(%1$s,%2$s)", elementName, attributeName); //$NON-NLS-1$
245         return mAttributeValues.get(key);
246     }
247 
248     /**
249      * Returns this list of possible values for an XML attribute.
250      * <p/>This should only be called for attributes for which possible values depend on the
251      * parent and great-grand-parent element node.
252      * <p/>The typical example of this is for the 'name' attribute under
253      * activity/intent-filter/action
254      * <p/>For attributes that have the same values no matter the parent node, use
255      * {@link #getEnumValueMap()}.
256      * @param elementName the name of the element containing the attribute.
257      * @param attributeName the name of the attribute
258      * @param greatGrandParentElementName the great-grand-parent node.
259      * @return an array of String with the possible values, or <code>null</code> if no values were
260      * found.
261      */
getAttributeValues(String elementName, String attributeName, String greatGrandParentElementName)262     public String[] getAttributeValues(String elementName, String attributeName,
263             String greatGrandParentElementName) {
264         if (greatGrandParentElementName != null) {
265             String key = String.format("(%1$s,%2$s,%3$s)", //$NON-NLS-1$
266                     greatGrandParentElementName, elementName, attributeName);
267             String[] values = mAttributeValues.get(key);
268             if (values != null) {
269                 return values;
270             }
271         }
272 
273         return getAttributeValues(elementName, attributeName);
274     }
275 
276     /**
277      * Returns the enum values map.
278      * <p/>The map defines the possible values for XML attributes. The key is the attribute name
279      * and the value is a map of (string, integer) in which the key (string) is the name of
280      * the value, and the Integer is the numerical value in the compiled binary XML files.
281      */
getEnumValueMap()282     public Map<String, Map<String, Integer>> getEnumValueMap() {
283         return mEnumValueMap;
284     }
285 
286     /**
287      * Returns the {@link ProjectResources} containing the Framework Resources.
288      */
getFrameworkResources()289     public ResourceRepository getFrameworkResources() {
290         return mFrameworkResources;
291     }
292 
293     /**
294      * Returns a {@link LayoutLibrary} object possibly containing a {@link LayoutBridge} object.
295      * <p/>If {@link LayoutLibrary#getBridge()} is <code>null</code>,
296      * {@link LayoutBridge#getStatus()} will contain the reason (either {@link LoadStatus#LOADING}
297      * or {@link LoadStatus#FAILED}).
298      * <p/>Valid {@link LayoutBridge} objects are always initialized before being returned.
299      */
getLayoutLibrary()300     public synchronized LayoutLibrary getLayoutLibrary() {
301         if (mLayoutBridgeInit == false && mLayoutLibrary.getStatus() == LoadStatus.LOADED) {
302             boolean ok = mLayoutLibrary.init(
303                     mTarget.getProperties(),
304                     new File(mTarget.getPath(IAndroidTarget.FONTS)),
305                     getEnumValueMap(),
306                     new LayoutLog() {
307 
308                         @Override
309                         public void error(String tag, String message, Throwable throwable,
310                                 Object data) {
311                             AdtPlugin.log(throwable, message);
312                         }
313 
314                         @Override
315                         public void error(String tag, String message, Object data) {
316                             AdtPlugin.log(IStatus.ERROR, message);
317                         }
318 
319                         @Override
320                         public void warning(String tag, String message, Object data) {
321                             AdtPlugin.log(IStatus.WARNING, message);
322                         }
323                     });
324             if (!ok) {
325                 AdtPlugin.log(IStatus.ERROR,
326                         "LayoutLibrary initialization failed");
327             }
328             mLayoutBridgeInit = true;
329         }
330 
331         return mLayoutLibrary;
332     }
333 
334     /**
335      * Sets the permission values
336      * @param permissionValues the list of permissions
337      */
setPermissions(String[] permissionValues)338     private void setPermissions(String[] permissionValues) {
339         setValues("(uses-permission,android:name)", permissionValues);   //$NON-NLS-1$
340         setValues("(application,android:permission)", permissionValues); //$NON-NLS-1$
341         setValues("(activity,android:permission)", permissionValues);    //$NON-NLS-1$
342         setValues("(receiver,android:permission)", permissionValues);    //$NON-NLS-1$
343         setValues("(service,android:permission)", permissionValues);     //$NON-NLS-1$
344         setValues("(provider,android:permission)", permissionValues);    //$NON-NLS-1$
345     }
346 
setIntentFilterActionsAndCategories(String[] activityIntentActions, String[] broadcastIntentActions, String[] serviceIntentActions, String[] intentCategoryValues)347     private void setIntentFilterActionsAndCategories(String[] activityIntentActions,
348             String[] broadcastIntentActions, String[] serviceIntentActions,
349             String[] intentCategoryValues) {
350         setValues("(activity,action,android:name)", activityIntentActions);  //$NON-NLS-1$
351         setValues("(receiver,action,android:name)", broadcastIntentActions); //$NON-NLS-1$
352         setValues("(service,action,android:name)", serviceIntentActions);    //$NON-NLS-1$
353         setValues("(category,android:name)", intentCategoryValues);          //$NON-NLS-1$
354     }
355 
setOptionalLibraries(String[] platformLibraries, IOptionalLibrary[] optionalLibraries)356     private void setOptionalLibraries(String[] platformLibraries,
357             IOptionalLibrary[] optionalLibraries) {
358 
359         ArrayList<String> libs = new ArrayList<String>();
360 
361         if (platformLibraries != null) {
362             for (String name : platformLibraries) {
363                 libs.add(name);
364             }
365         }
366 
367         if (optionalLibraries != null) {
368             for (int i = 0; i < optionalLibraries.length; i++) {
369                 libs.add(optionalLibraries[i].getName());
370             }
371         }
372         setValues("(uses-library,android:name)",  libs.toArray(new String[libs.size()]));
373     }
374 
375     /**
376      * Sets a (name, values) pair in the hash map.
377      * <p/>
378      * If the name is already present in the map, it is first removed.
379      * @param name the name associated with the values.
380      * @param values The values to add.
381      */
setValues(String name, String[] values)382     private void setValues(String name, String[] values) {
383         mAttributeValues.remove(name);
384         mAttributeValues.put(name, values);
385     }
386 
dispose()387     public void dispose() {
388         if (mLayoutLibrary != null) {
389             mLayoutLibrary.dispose();
390         }
391     }
392 }
393