OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / sdk / eclipse / plugins / com.android.ide.eclipse.adt / src / com / android / ide / eclipse / adt / internal / editors / xml / descriptors / XmlDescriptors.java
diff --git a/sdk/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java b/sdk/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java
new file mode 100644 (file)
index 0000000..b807aa1
--- /dev/null
@@ -0,0 +1,365 @@
+/*
+ * 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.xml.descriptors;
+
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_PREFIX;
+
+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 com.android.sdklib.SdkConstants;
+
+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 XmlDescriptors 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. */
+    public DocumentDescriptor getDescriptor() {
+        return mDescriptor;
+    }
+
+    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() {
+            public ElementDescriptor getDescriptor() {
+                return mSearchDescriptor;
+            }
+
+            public ElementDescriptor[] getRootElementDescriptors() {
+                return mSearchDescriptor.getChildren();
+            }
+        };
+    }
+
+    public IDescriptorProvider getPreferencesProvider() {
+        return new IDescriptorProvider() {
+            public ElementDescriptor getDescriptor() {
+                return mPrefDescriptor;
+            }
+
+            public ElementDescriptor[] getRootElementDescriptors() {
+                return mPrefDescriptor.getChildren();
+            }
+        };
+    }
+
+    public IDescriptorProvider getAppWidgetProvider() {
+        return new IDescriptorProvider() {
+            public ElementDescriptor getDescriptor() {
+                return mAppWidgetDescriptor;
+            }
+
+            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_PREFIX,
+                SdkConstants.NS_RESOURCES);
+
+        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 */);
+    }
+}