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