Home | History | Annotate | Download | only in uimodel
      1 /*
      2  * Copyright (C) 2008 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.uimodel;
     18 
     19 import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
     20 import com.android.ide.eclipse.adt.internal.editors.uimodel.IUiUpdateListener.UiUpdateState;
     21 
     22 import org.w3c.dom.Document;
     23 import org.w3c.dom.Node;
     24 
     25 import java.util.ArrayList;
     26 import java.util.List;
     27 
     28 /**
     29  * Represents an XML document node that can be modified by the user interface in the XML editor.
     30  * <p/>
     31  * The structure of a given {@link UiDocumentNode} is declared by a corresponding
     32  * {@link DocumentDescriptor}.
     33  */
     34 public class UiDocumentNode extends UiElementNode {
     35 
     36     /**
     37      * Creates a new {@link UiDocumentNode} described by a given {@link DocumentDescriptor}.
     38      *
     39      * @param documentDescriptor The {@link DocumentDescriptor} for the XML node. Cannot be null.
     40      */
     41     public UiDocumentNode(DocumentDescriptor documentDescriptor) {
     42         super(documentDescriptor);
     43     }
     44 
     45     /**
     46      * Computes a short string describing the UI node suitable for tree views.
     47      * Uses the element's attribute "android:name" if present, or the "android:label" one
     48      * followed by the element's name.
     49      *
     50      * @return A short string describing the UI node suitable for tree views.
     51      */
     52     @Override
     53     public String getShortDescription() {
     54         return "Document"; //$NON-NLS-1$
     55     }
     56 
     57     /**
     58      * Computes a "breadcrumb trail" description for this node.
     59      *
     60      * @param include_root Whether to include the root (e.g. "Manifest") or not. Has no effect
     61      *                     when called on the root node itself.
     62      * @return The "breadcrumb trail" description for this node.
     63      */
     64     @Override
     65     public String getBreadcrumbTrailDescription(boolean include_root) {
     66         return "Document"; //$NON-NLS-1$
     67     }
     68 
     69     /**
     70      * This method throws an exception when attempted to assign a parent, since XML documents
     71      * cannot have a parent. It is OK to assign null.
     72      */
     73     @Override
     74     protected void setUiParent(UiElementNode parent) {
     75         if (parent != null) {
     76             // DEBUG. Change to log warning.
     77             throw new UnsupportedOperationException("Documents can't have UI parents"); //$NON-NLS-1$
     78         }
     79         super.setUiParent(null);
     80     }
     81 
     82     /**
     83      * Populate this element node with all values from the given XML node.
     84      *
     85      * This fails if the given XML node has a different element name -- it won't change the
     86      * type of this ui node.
     87      *
     88      * This method can be both used for populating values the first time and updating values
     89      * after the XML model changed.
     90      *
     91      * @param xml_node The XML node to mirror
     92      * @return Returns true if the XML structure has changed (nodes added, removed or replaced)
     93      */
     94     @Override
     95     public boolean loadFromXmlNode(Node xml_node) {
     96         boolean structure_changed = (getXmlDocument() != xml_node);
     97         setXmlDocument((Document) xml_node);
     98         structure_changed |= super.loadFromXmlNode(xml_node);
     99         if (structure_changed) {
    100             invokeUiUpdateListeners(UiUpdateState.CHILDREN_CHANGED);
    101         }
    102         return structure_changed;
    103     }
    104 
    105     /**
    106      * This method throws an exception if there is no underlying XML document.
    107      * <p/>
    108      * XML documents cannot be created per se -- they are a by-product of the StructuredEditor
    109      * XML parser.
    110      *
    111      * @return The current value of getXmlDocument().
    112      */
    113     @Override
    114     public Node createXmlNode() {
    115         if (getXmlDocument() == null) {
    116             // By design, a document node cannot be created, it is owned by the XML parser.
    117             // By "design" this should never happen since the XML parser always creates an XML
    118             // document container, even for an empty file.
    119             throw new UnsupportedOperationException("Documents cannot be created"); //$NON-NLS-1$
    120         }
    121         return getXmlDocument();
    122     }
    123 
    124     /**
    125      * This method throws an exception and does not even try to delete the XML document.
    126      * <p/>
    127      * XML documents cannot be deleted per se -- they are a by-product of the StructuredEditor
    128      * XML parser.
    129      *
    130      * @return The removed node or null if it didn't exist in the first place.
    131      */
    132     @Override
    133     public Node deleteXmlNode() {
    134         // DEBUG. Change to log warning.
    135         throw new UnsupportedOperationException("Documents cannot be deleted"); //$NON-NLS-1$
    136     }
    137 
    138     /**
    139      * Returns all elements in this document.
    140      *
    141      * @param document the document
    142      * @return all elements in the document
    143      */
    144     public static List<UiElementNode> getAllElements(UiDocumentNode document) {
    145         List<UiElementNode> elements = new ArrayList<UiElementNode>(64);
    146         for (UiElementNode child : document.getUiChildren()) {
    147             addElements(child, elements);
    148         }
    149         return elements;
    150     }
    151 
    152     private static void addElements(UiElementNode node, List<UiElementNode> elements) {
    153         elements.add(node);
    154 
    155         for (UiElementNode child : node.getUiChildren()) {
    156             addElements(child, elements);
    157         }
    158     }
    159 }
    160 
    161