2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.eclipse.org/org/documents/epl-v10.php
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.
17 package com.android.ide.eclipse.adt.internal.editors.xml.descriptors;
19 import com.android.ide.eclipse.adt.AndroidConstants;
20 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
21 import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
22 import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
23 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
24 import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
25 import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
26 import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
27 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
28 import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo;
29 import com.android.ide.eclipse.adt.internal.resources.ViewClassInfo;
30 import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo;
31 import com.android.sdklib.SdkConstants;
33 import java.util.ArrayList;
38 * Description of the /res/xml structure.
39 * Currently supports the <searchable> and <preferences> root nodes.
41 public final class XmlDescriptors implements IDescriptorProvider {
43 // Public attributes names, attributes descriptors and elements descriptors referenced
45 public static final String PREF_KEY_ATTR = "key"; //$NON-NLS-1$
47 /** The root document descriptor for both searchable and preferences. */
48 private DocumentDescriptor mDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
50 /** The root document descriptor for searchable. */
51 private DocumentDescriptor mSearchDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
53 /** The root document descriptor for preferences. */
54 private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
56 /** The root document descriptor for widget provider. */
57 private DocumentDescriptor mAppWidgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
59 /** @return the root descriptor for both searchable and preferences. */
60 public DocumentDescriptor getDescriptor() {
64 public ElementDescriptor[] getRootElementDescriptors() {
65 return mDescriptor.getChildren();
68 /** @return the root descriptor for searchable. */
69 public DocumentDescriptor getSearchableDescriptor() {
70 return mSearchDescriptor;
73 /** @return the root descriptor for preferences. */
74 public DocumentDescriptor getPreferencesDescriptor() {
75 return mPrefDescriptor;
78 /** @return the root descriptor for widget providers. */
79 public DocumentDescriptor getAppWidgetDescriptor() {
80 return mAppWidgetDescriptor;
83 public IDescriptorProvider getSearchableProvider() {
84 return new IDescriptorProvider() {
85 public ElementDescriptor getDescriptor() {
86 return mSearchDescriptor;
89 public ElementDescriptor[] getRootElementDescriptors() {
90 return mSearchDescriptor.getChildren();
95 public IDescriptorProvider getPreferencesProvider() {
96 return new IDescriptorProvider() {
97 public ElementDescriptor getDescriptor() {
98 return mPrefDescriptor;
101 public ElementDescriptor[] getRootElementDescriptors() {
102 return mPrefDescriptor.getChildren();
107 public IDescriptorProvider getAppWidgetProvider() {
108 return new IDescriptorProvider() {
109 public ElementDescriptor getDescriptor() {
110 return mAppWidgetDescriptor;
113 public ElementDescriptor[] getRootElementDescriptors() {
114 return mAppWidgetDescriptor.getChildren();
120 * Updates the document descriptor.
122 * It first computes the new children of the descriptor and then updates them
125 * @param searchableStyleMap The map style=>attributes for <searchable> from the attrs.xml file
126 * @param appWidgetStyleMap The map style=>attributes for <appwidget-provider> from the attrs.xml file
127 * @param prefs The list of non-group preference descriptions
128 * @param prefGroups The list of preference group descriptions
130 public synchronized void updateDescriptors(
131 Map<String, DeclareStyleableInfo> searchableStyleMap,
132 Map<String, DeclareStyleableInfo> appWidgetStyleMap,
133 ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
135 XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
136 "android", //$NON-NLS-1$
137 SdkConstants.NS_RESOURCES);
139 ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns);
140 ElementDescriptor appWidget = createAppWidgetProviderInfo(appWidgetStyleMap, xmlns);
141 ElementDescriptor preferences = createPreference(prefs, prefGroups, xmlns);
142 ArrayList<ElementDescriptor> list = new ArrayList<ElementDescriptor>();
143 if (searchable != null) {
144 list.add(searchable);
145 mSearchDescriptor.setChildren(new ElementDescriptor[]{ searchable });
147 if (appWidget != null) {
149 mAppWidgetDescriptor.setChildren(new ElementDescriptor[]{ appWidget });
151 if (preferences != null) {
152 list.add(preferences);
153 mPrefDescriptor.setChildren(new ElementDescriptor[]{ preferences });
156 if (list.size() > 0) {
157 mDescriptor.setChildren(list.toArray(new ElementDescriptor[list.size()]));
161 //-------------------------
162 // Creation of <searchable>
163 //-------------------------
166 * Returns the new ElementDescriptor for <searchable>
168 private ElementDescriptor createSearchable(
169 Map<String, DeclareStyleableInfo> searchableStyleMap,
170 XmlnsAttributeDescriptor xmlns) {
172 ElementDescriptor action_key = createElement(searchableStyleMap,
173 "SearchableActionKey", //$NON-NLS-1$ styleName
174 "actionkey", //$NON-NLS-1$ xmlName
175 "Action Key", // uiName
177 null, // extraAttribute
178 null, // childrenElements
179 false /* mandatory */ );
181 ElementDescriptor searchable = createElement(searchableStyleMap,
182 "Searchable", //$NON-NLS-1$ styleName
183 "searchable", //$NON-NLS-1$ xmlName
184 "Searchable", // uiName
186 xmlns, // extraAttribute
187 new ElementDescriptor[] { action_key }, // childrenElements
188 false /* mandatory */ );
193 * Returns the new ElementDescriptor for <appwidget-provider>
195 private ElementDescriptor createAppWidgetProviderInfo(
196 Map<String, DeclareStyleableInfo> appWidgetStyleMap,
197 XmlnsAttributeDescriptor xmlns) {
199 if (appWidgetStyleMap == null) {
203 ElementDescriptor appWidget = createElement(appWidgetStyleMap,
204 "AppWidgetProviderInfo", //$NON-NLS-1$ styleName
205 "appwidget-provider", //$NON-NLS-1$ xmlName
206 "AppWidget Provider", // uiName
208 xmlns, // extraAttribute
209 null, // childrenElements
210 false /* mandatory */ );
215 * Returns a new ElementDescriptor constructed from the information given here
216 * and the javadoc & attributes extracted from the style map if any.
218 private ElementDescriptor createElement(
219 Map<String, DeclareStyleableInfo> styleMap, String styleName,
220 String xmlName, String uiName, String sdkUrl,
221 AttributeDescriptor extraAttribute,
222 ElementDescriptor[] childrenElements, boolean mandatory) {
224 ElementDescriptor element = new ElementDescriptor(xmlName, uiName, null, sdkUrl,
225 null, childrenElements, mandatory);
227 return updateElement(element, styleMap, styleName, extraAttribute);
231 * Updates an ElementDescriptor with the javadoc & attributes extracted from the style
234 private ElementDescriptor updateElement(ElementDescriptor element,
235 Map<String, DeclareStyleableInfo> styleMap,
237 AttributeDescriptor extraAttribute) {
238 ArrayList<AttributeDescriptor> descs = new ArrayList<AttributeDescriptor>();
240 DeclareStyleableInfo style = styleMap != null ? styleMap.get(styleName) : null;
242 DescriptorsUtils.appendAttributes(descs,
244 SdkConstants.NS_RESOURCES,
245 style.getAttributes(),
246 null, // requiredAttributes
248 element.setTooltip(style.getJavaDoc());
251 if (extraAttribute != null) {
252 descs.add(extraAttribute);
255 element.setAttributes(descs.toArray(new AttributeDescriptor[descs.size()]));
259 //--------------------------
260 // Creation of <Preferences>
261 //--------------------------
264 * Returns the new ElementDescriptor for <Preferences>
266 private ElementDescriptor createPreference(ViewClassInfo[] prefs,
267 ViewClassInfo[] prefGroups, XmlnsAttributeDescriptor xmlns) {
269 ArrayList<ElementDescriptor> newPrefs = new ArrayList<ElementDescriptor>();
271 for (ViewClassInfo info : prefs) {
272 ElementDescriptor desc = convertPref(info);
277 ElementDescriptor topPreferences = null;
279 ArrayList<ElementDescriptor> newGroups = new ArrayList<ElementDescriptor>();
280 if (prefGroups != null) {
281 for (ViewClassInfo info : prefGroups) {
282 ElementDescriptor desc = convertPref(info);
285 if (info.getCanonicalClassName() == AndroidConstants.CLASS_PREFERENCES) {
286 topPreferences = desc;
291 ArrayList<ElementDescriptor> everything = new ArrayList<ElementDescriptor>();
292 everything.addAll(newGroups);
293 everything.addAll(newPrefs);
294 ElementDescriptor[] newArray = everything.toArray(new ElementDescriptor[everything.size()]);
296 // Link all groups to everything else here.. recursively
297 for (ElementDescriptor layoutDesc : newGroups) {
298 layoutDesc.setChildren(newArray);
301 // The "top" element to be returned corresponds to the class "Preferences".
302 // Its descriptor has already been created. However the root one also needs
303 // the hidden xmlns:android definition..
304 if (topPreferences != null) {
305 AttributeDescriptor[] attrs = topPreferences.getAttributes();
306 AttributeDescriptor[] newAttrs = new AttributeDescriptor[attrs.length + 1];
307 System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
308 newAttrs[attrs.length] = xmlns;
309 return new ElementDescriptor(
310 topPreferences.getXmlName(),
311 topPreferences.getUiName(),
312 topPreferences.getTooltip(),
313 topPreferences.getSdkUrl(),
315 topPreferences.getChildren(),
316 false /* mandatory */);
323 * Creates an element descriptor from a given {@link ViewClassInfo}.
325 private ElementDescriptor convertPref(ViewClassInfo info) {
326 String xml_name = info.getShortClassName();
327 String tooltip = info.getJavaDoc();
329 // Process all Preference attributes
330 ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
331 DescriptorsUtils.appendAttributes(attributes,
333 SdkConstants.NS_RESOURCES,
334 info.getAttributes(),
335 null, // requiredAttributes
338 for (ViewClassInfo link = info.getSuperClass();
340 link = link.getSuperClass()) {
341 AttributeInfo[] attrList = link.getAttributes();
342 if (attrList.length > 0) {
343 attributes.add(new SeparatorAttributeDescriptor(
344 String.format("Attributes from %1$s", link.getShortClassName())));
345 DescriptorsUtils.appendAttributes(attributes,
347 SdkConstants.NS_RESOURCES,
349 null, // requiredAttributes
354 return new ViewElementDescriptor(xml_name,
356 info.getCanonicalClassName(),
359 attributes.toArray(new AttributeDescriptor[attributes.size()]),
362 false /* mandatory */);