diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/otherxml/descriptors/OtherXmlDescriptors.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/otherxml/descriptors/OtherXmlDescriptors.java | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/otherxml/descriptors/OtherXmlDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/otherxml/descriptors/OtherXmlDescriptors.java new file mode 100644 index 000000000..7f3ed0939 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/otherxml/descriptors/OtherXmlDescriptors.java @@ -0,0 +1,373 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ide.eclipse.adt.internal.editors.otherxml.descriptors; + +import static com.android.SdkConstants.ANDROID_NS_NAME; +import static com.android.SdkConstants.ANDROID_URI; + +import com.android.SdkConstants; +import com.android.ide.common.resources.platform.AttributeInfo; +import com.android.ide.common.resources.platform.DeclareStyleableInfo; +import com.android.ide.common.resources.platform.ViewClassInfo; +import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; +import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider; +import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor; + +import java.util.ArrayList; +import java.util.Map; + + +/** + * Description of the /res/xml structure. + * Currently supports the <searchable> and <preferences> root nodes. + */ +public final class OtherXmlDescriptors implements IDescriptorProvider { + + // Public attributes names, attributes descriptors and elements descriptors referenced + // elsewhere. + public static final String PREF_KEY_ATTR = "key"; //$NON-NLS-1$ + + /** The root document descriptor for both searchable and preferences. */ + private DocumentDescriptor mDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ + + /** The root document descriptor for searchable. */ + private DocumentDescriptor mSearchDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ + + /** The root document descriptor for preferences. */ + private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ + + /** The root document descriptor for widget provider. */ + private DocumentDescriptor mAppWidgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ + + /** @return the root descriptor for both searchable and preferences. */ + @Override + public DocumentDescriptor getDescriptor() { + return mDescriptor; + } + + @Override + public ElementDescriptor[] getRootElementDescriptors() { + return mDescriptor.getChildren(); + } + + /** @return the root descriptor for searchable. */ + public DocumentDescriptor getSearchableDescriptor() { + return mSearchDescriptor; + } + + /** @return the root descriptor for preferences. */ + public DocumentDescriptor getPreferencesDescriptor() { + return mPrefDescriptor; + } + + /** @return the root descriptor for widget providers. */ + public DocumentDescriptor getAppWidgetDescriptor() { + return mAppWidgetDescriptor; + } + + public IDescriptorProvider getSearchableProvider() { + return new IDescriptorProvider() { + @Override + public ElementDescriptor getDescriptor() { + return mSearchDescriptor; + } + + @Override + public ElementDescriptor[] getRootElementDescriptors() { + return mSearchDescriptor.getChildren(); + } + }; + } + + public IDescriptorProvider getPreferencesProvider() { + return new IDescriptorProvider() { + @Override + public ElementDescriptor getDescriptor() { + return mPrefDescriptor; + } + + @Override + public ElementDescriptor[] getRootElementDescriptors() { + return mPrefDescriptor.getChildren(); + } + }; + } + + public IDescriptorProvider getAppWidgetProvider() { + return new IDescriptorProvider() { + @Override + public ElementDescriptor getDescriptor() { + return mAppWidgetDescriptor; + } + + @Override + public ElementDescriptor[] getRootElementDescriptors() { + return mAppWidgetDescriptor.getChildren(); + } + }; + } + + /** + * Updates the document descriptor. + * <p/> + * It first computes the new children of the descriptor and then updates them + * all at once. + * + * @param searchableStyleMap The map style=>attributes for <searchable> from the attrs.xml file + * @param appWidgetStyleMap The map style=>attributes for <appwidget-provider> from the attrs.xml file + * @param prefs The list of non-group preference descriptions + * @param prefGroups The list of preference group descriptions + */ + public synchronized void updateDescriptors( + Map<String, DeclareStyleableInfo> searchableStyleMap, + Map<String, DeclareStyleableInfo> appWidgetStyleMap, + ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) { + + XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(ANDROID_NS_NAME, + ANDROID_URI); + + ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns); + ElementDescriptor appWidget = createAppWidgetProviderInfo(appWidgetStyleMap, xmlns); + ElementDescriptor preferences = createPreference(prefs, prefGroups, xmlns); + ArrayList<ElementDescriptor> list = new ArrayList<ElementDescriptor>(); + if (searchable != null) { + list.add(searchable); + mSearchDescriptor.setChildren(new ElementDescriptor[]{ searchable }); + } + if (appWidget != null) { + list.add(appWidget); + mAppWidgetDescriptor.setChildren(new ElementDescriptor[]{ appWidget }); + } + if (preferences != null) { + list.add(preferences); + mPrefDescriptor.setChildren(new ElementDescriptor[]{ preferences }); + } + + if (list.size() > 0) { + mDescriptor.setChildren(list.toArray(new ElementDescriptor[list.size()])); + } + } + + //------------------------- + // Creation of <searchable> + //------------------------- + + /** + * Returns the new ElementDescriptor for <searchable> + */ + private ElementDescriptor createSearchable( + Map<String, DeclareStyleableInfo> searchableStyleMap, + XmlnsAttributeDescriptor xmlns) { + + ElementDescriptor action_key = createElement(searchableStyleMap, + "SearchableActionKey", //$NON-NLS-1$ styleName + "actionkey", //$NON-NLS-1$ xmlName + "Action Key", // uiName + null, // sdk url + null, // extraAttribute + null, // childrenElements + false /* mandatory */ ); + + ElementDescriptor searchable = createElement(searchableStyleMap, + "Searchable", //$NON-NLS-1$ styleName + "searchable", //$NON-NLS-1$ xmlName + "Searchable", // uiName + null, // sdk url + xmlns, // extraAttribute + new ElementDescriptor[] { action_key }, // childrenElements + false /* mandatory */ ); + return searchable; + } + + /** + * Returns the new ElementDescriptor for <appwidget-provider> + */ + private ElementDescriptor createAppWidgetProviderInfo( + Map<String, DeclareStyleableInfo> appWidgetStyleMap, + XmlnsAttributeDescriptor xmlns) { + + if (appWidgetStyleMap == null) { + return null; + } + + ElementDescriptor appWidget = createElement(appWidgetStyleMap, + "AppWidgetProviderInfo", //$NON-NLS-1$ styleName + "appwidget-provider", //$NON-NLS-1$ xmlName + "AppWidget Provider", // uiName + null, // sdk url + xmlns, // extraAttribute + null, // childrenElements + false /* mandatory */ ); + return appWidget; + } + + /** + * Returns a new ElementDescriptor constructed from the information given here + * and the javadoc & attributes extracted from the style map if any. + */ + private ElementDescriptor createElement( + Map<String, DeclareStyleableInfo> styleMap, String styleName, + String xmlName, String uiName, String sdkUrl, + AttributeDescriptor extraAttribute, + ElementDescriptor[] childrenElements, boolean mandatory) { + + ElementDescriptor element = new ElementDescriptor(xmlName, uiName, null, sdkUrl, + null, childrenElements, mandatory); + + return updateElement(element, styleMap, styleName, extraAttribute); + } + + /** + * Updates an ElementDescriptor with the javadoc & attributes extracted from the style + * map if any. + */ + private ElementDescriptor updateElement(ElementDescriptor element, + Map<String, DeclareStyleableInfo> styleMap, + String styleName, + AttributeDescriptor extraAttribute) { + ArrayList<AttributeDescriptor> descs = new ArrayList<AttributeDescriptor>(); + + DeclareStyleableInfo style = styleMap != null ? styleMap.get(styleName) : null; + if (style != null) { + DescriptorsUtils.appendAttributes(descs, + null, // elementName + SdkConstants.NS_RESOURCES, + style.getAttributes(), + null, // requiredAttributes + null); // overrides + element.setTooltip(style.getJavaDoc()); + } + + if (extraAttribute != null) { + descs.add(extraAttribute); + } + + element.setAttributes(descs.toArray(new AttributeDescriptor[descs.size()])); + return element; + } + + //-------------------------- + // Creation of <Preferences> + //-------------------------- + + /** + * Returns the new ElementDescriptor for <Preferences> + */ + private ElementDescriptor createPreference(ViewClassInfo[] prefs, + ViewClassInfo[] prefGroups, XmlnsAttributeDescriptor xmlns) { + + ArrayList<ElementDescriptor> newPrefs = new ArrayList<ElementDescriptor>(); + if (prefs != null) { + for (ViewClassInfo info : prefs) { + ElementDescriptor desc = convertPref(info); + newPrefs.add(desc); + } + } + + ElementDescriptor topPreferences = null; + + ArrayList<ElementDescriptor> newGroups = new ArrayList<ElementDescriptor>(); + if (prefGroups != null) { + for (ViewClassInfo info : prefGroups) { + ElementDescriptor desc = convertPref(info); + newGroups.add(desc); + + if (info.getFullClassName() == SdkConstants.CLASS_PREFERENCES) { + topPreferences = desc; + } + } + } + + ArrayList<ElementDescriptor> everything = new ArrayList<ElementDescriptor>(); + everything.addAll(newGroups); + everything.addAll(newPrefs); + ElementDescriptor[] newArray = everything.toArray(new ElementDescriptor[everything.size()]); + + // Link all groups to everything else here.. recursively + for (ElementDescriptor layoutDesc : newGroups) { + layoutDesc.setChildren(newArray); + } + + // The "top" element to be returned corresponds to the class "Preferences". + // Its descriptor has already been created. However the root one also needs + // the hidden xmlns:android definition.. + if (topPreferences != null) { + AttributeDescriptor[] attrs = topPreferences.getAttributes(); + AttributeDescriptor[] newAttrs = new AttributeDescriptor[attrs.length + 1]; + System.arraycopy(attrs, 0, newAttrs, 0, attrs.length); + newAttrs[attrs.length] = xmlns; + return new ElementDescriptor( + topPreferences.getXmlName(), + topPreferences.getUiName(), + topPreferences.getTooltip(), + topPreferences.getSdkUrl(), + newAttrs, + topPreferences.getChildren(), + false /* mandatory */); + } else { + return null; + } + } + + /** + * Creates an element descriptor from a given {@link ViewClassInfo}. + */ + private ElementDescriptor convertPref(ViewClassInfo info) { + String xml_name = info.getShortClassName(); + String tooltip = info.getJavaDoc(); + + // Process all Preference attributes + ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>(); + DescriptorsUtils.appendAttributes(attributes, + null, // elementName + SdkConstants.NS_RESOURCES, + info.getAttributes(), + null, // requiredAttributes + null); // overrides + + for (ViewClassInfo link = info.getSuperClass(); + link != null; + link = link.getSuperClass()) { + AttributeInfo[] attrList = link.getAttributes(); + if (attrList.length > 0) { + attributes.add(new SeparatorAttributeDescriptor( + String.format("Attributes from %1$s", link.getShortClassName()))); + DescriptorsUtils.appendAttributes(attributes, + null, // elementName + SdkConstants.NS_RESOURCES, + attrList, + null, // requiredAttributes + null); // overrides + } + } + + return new ViewElementDescriptor(xml_name, + xml_name, // ui_name + info.getFullClassName(), + tooltip, + null, // sdk_url + attributes.toArray(new AttributeDescriptor[attributes.size()]), + null, + null, // children + false /* mandatory */); + } +} |