Home | History | Annotate | Download | only in model
      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.editors.manifest.model;
     18 
     19 import com.android.SdkConstants;
     20 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
     21 import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
     22 import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.ManifestElementDescriptor;
     23 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
     24 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
     25 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
     26 
     27 import org.w3c.dom.Element;
     28 
     29 /**
     30  * Represents an XML node that can be modified by the user interface in the XML editor.
     31  * <p/>
     32  * Each tree viewer used in the application page's parts needs to keep a model representing
     33  * each underlying node in the tree. This interface represents the base type for such a node.
     34  * <p/>
     35  * Each node acts as an intermediary model between the actual XML model (the real data support)
     36  * and the tree viewers or the corresponding page parts.
     37  * <p/>
     38  * Element nodes don't contain data per se. Their data is contained in their attributes
     39  * as well as their children's attributes, see {@link UiAttributeNode}.
     40  * <p/>
     41  * The structure of a given {@link UiElementNode} is declared by a corresponding
     42  * {@link ElementDescriptor}.
     43  */
     44 public final class UiManifestElementNode extends UiElementNode {
     45 
     46     /**
     47      * Creates a new {@link UiElementNode} described by a given {@link ElementDescriptor}.
     48      *
     49      * @param elementDescriptor The {@link ElementDescriptor} for the XML node. Cannot be null.
     50      */
     51     public UiManifestElementNode(ManifestElementDescriptor elementDescriptor) {
     52         super(elementDescriptor);
     53     }
     54 
     55     /**
     56      * Computes a short string describing the UI node suitable for tree views.
     57      * Uses the element's attribute "android:name" if present, or the "android:label" one
     58      * followed by the element's name if not repeated.
     59      *
     60      * @return A short string describing the UI node suitable for tree views.
     61      */
     62     @Override
     63     public String getShortDescription() {
     64         AndroidTargetData target = getAndroidTarget();
     65         AndroidManifestDescriptors manifestDescriptors = null;
     66         if (target != null) {
     67             manifestDescriptors = target.getManifestDescriptors();
     68         }
     69 
     70         String name = getDescriptor().getUiName();
     71 
     72         if (manifestDescriptors != null &&
     73                 getXmlNode() != null &&
     74                 getXmlNode() instanceof Element &&
     75                 getXmlNode().hasAttributes()) {
     76 
     77             // Application and Manifest nodes have a special treatment: they are unique nodes
     78             // so we don't bother trying to differentiate their strings and we fall back to
     79             // just using the UI name below.
     80             ElementDescriptor desc = getDescriptor();
     81             if (desc != manifestDescriptors.getManifestElement() &&
     82                     desc != manifestDescriptors.getApplicationElement()) {
     83                 Element elem = (Element) getXmlNode();
     84                 String attr = _Element_getAttributeNS(elem,
     85                                     SdkConstants.NS_RESOURCES,
     86                                     AndroidManifestDescriptors.ANDROID_NAME_ATTR);
     87                 if (attr == null || attr.length() == 0) {
     88                     attr = _Element_getAttributeNS(elem,
     89                                     SdkConstants.NS_RESOURCES,
     90                                     AndroidManifestDescriptors.ANDROID_LABEL_ATTR);
     91                 }
     92                 if (attr != null && attr.length() > 0) {
     93                     // If the ui name is repeated in the attribute value, don't use it.
     94                     // Typical case is to avoid ".pkg.MyActivity (Activity)".
     95                     if (attr.contains(name)) {
     96                         return attr;
     97                     } else {
     98                         return String.format("%1$s (%2$s)", attr, name);
     99                     }
    100                 }
    101             }
    102         }
    103 
    104         return String.format("%1$s", name);
    105     }
    106 
    107     /**
    108      * Retrieves an attribute value by local name and namespace URI.
    109      * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>]
    110      * , applications must use the value <code>null</code> as the
    111      * <code>namespaceURI</code> parameter for methods if they wish to have
    112      * no namespace.
    113      * <p/>
    114      * Note: This is a wrapper around {@link Element#getAttributeNS(String, String)}.
    115      * In some versions of webtools, the getAttributeNS implementation crashes with an NPE.
    116      * This wrapper will return null instead.
    117      *
    118      * @see Element#getAttributeNS(String, String)
    119      * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=318108">https://bugs.eclipse.org/bugs/show_bug.cgi?id=318108</a>
    120      * @return The result from {@link Element#getAttributeNS(String, String)} or or an empty string.
    121      */
    122     private String _Element_getAttributeNS(Element element,
    123             String namespaceURI,
    124             String localName) {
    125         try {
    126             return element.getAttributeNS(namespaceURI, localName);
    127         } catch (Exception ignore) {
    128             return "";
    129         }
    130     }
    131 }
    132 
    133