| /* |
| * 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.menu.descriptors; |
| |
| import static com.android.SdkConstants.ANDROID_NS_NAME; |
| import static com.android.SdkConstants.ANDROID_URI; |
| import static com.android.SdkConstants.TAG_MENU; |
| |
| import com.android.ide.common.resources.platform.DeclareStyleableInfo; |
| import com.android.ide.eclipse.adt.AdtUtils; |
| 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.ElementDescriptor; |
| import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider; |
| import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor; |
| |
| import java.util.ArrayList; |
| import java.util.Map; |
| |
| /** |
| * Complete description of the menu structure. |
| */ |
| public final class MenuDescriptors implements IDescriptorProvider { |
| |
| /** The root element descriptor. */ |
| private ElementDescriptor mDescriptor = null; |
| |
| /** @return the root descriptor. */ |
| @Override |
| public ElementDescriptor getDescriptor() { |
| return mDescriptor; |
| } |
| |
| @Override |
| public ElementDescriptor[] getRootElementDescriptors() { |
| return mDescriptor.getChildren(); |
| } |
| |
| /** |
| * Updates the document descriptor. |
| * <p/> |
| * It first computes the new children of the descriptor and then updates them |
| * all at once. |
| * |
| * @param styleMap The map style => attributes from the attrs.xml file |
| */ |
| public synchronized void updateDescriptors(Map<String, DeclareStyleableInfo> styleMap) { |
| |
| // There are 3 elements: menu, item and group. |
| // The root element MUST be a menu. |
| // A top menu can contain items or group: |
| // - top groups can contain top items |
| // - top items can contain sub-menus |
| // A sub menu can contains sub items or sub groups: |
| // - sub groups can contain sub items |
| // - sub items cannot contain anything |
| |
| if (mDescriptor == null) { |
| mDescriptor = createElement(styleMap, |
| TAG_MENU, // xmlName |
| "Menu", // uiName, |
| null, // TODO SDK URL |
| null, // extraAttribute |
| null, // childrenElements, |
| true /* mandatory */); |
| } |
| |
| // -- sub menu can have sub_items, sub_groups but not sub_menus |
| |
| ElementDescriptor sub_item = createElement(styleMap, |
| "item", // xmlName //$NON-NLS-1$ |
| "Item", // uiName, |
| null, // TODO SDK URL |
| null, // extraAttribute |
| null, // childrenElements, |
| false /* mandatory */); |
| |
| ElementDescriptor sub_group = createElement(styleMap, |
| "group", // xmlName //$NON-NLS-1$ |
| "Group", // uiName, |
| null, // TODO SDK URL |
| null, // extraAttribute |
| new ElementDescriptor[] { sub_item }, // childrenElements, |
| false /* mandatory */); |
| |
| ElementDescriptor sub_menu = createElement(styleMap, |
| TAG_MENU, // xmlName |
| "Sub-Menu", // uiName, |
| null, // TODO SDK URL |
| null, // extraAttribute |
| new ElementDescriptor[] { sub_item, sub_group }, // childrenElements, |
| true /* mandatory */); |
| |
| // -- top menu can have all top groups and top items (which can have sub menus) |
| |
| ElementDescriptor top_item = createElement(styleMap, |
| "item", // xmlName //$NON-NLS-1$ |
| "Item", // uiName, |
| null, // TODO SDK URL |
| null, // extraAttribute |
| new ElementDescriptor[] { sub_menu }, // childrenElements, |
| false /* mandatory */); |
| |
| ElementDescriptor top_group = createElement(styleMap, |
| "group", // xmlName //$NON-NLS-1$ |
| "Group", // uiName, |
| null, // TODO SDK URL |
| null, // extraAttribute |
| new ElementDescriptor[] { top_item }, // childrenElements, |
| false /* mandatory */); |
| |
| XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(ANDROID_NS_NAME, |
| ANDROID_URI); |
| |
| updateElement(mDescriptor, styleMap, "Menu", xmlns); //$NON-NLS-1$ |
| mDescriptor.setChildren(new ElementDescriptor[] { top_item, top_group }); |
| } |
| |
| /** |
| * 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 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, |
| getStyleName(xmlName), |
| 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 |
| ANDROID_URI, |
| 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; |
| } |
| |
| /** |
| * Returns the style name (i.e. the <declare-styleable> name found in attrs.xml) |
| * for a given XML element name. |
| * <p/> |
| * The rule is that all elements have for style name: |
| * - their xml name capitalized |
| * - a "Menu" prefix, except for <menu> itself which is just "Menu". |
| */ |
| private String getStyleName(String xmlName) { |
| String styleName = AdtUtils.capitalize(xmlName); |
| |
| // This is NOT the UI Name but the expected internal style name |
| final String MENU_STYLE_BASE_NAME = "Menu"; //$NON-NLS-1$ |
| |
| if (!styleName.equals(MENU_STYLE_BASE_NAME)) { |
| styleName = MENU_STYLE_BASE_NAME + styleName; |
| } |
| return styleName; |
| } |
| } |