1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 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 #ifndef AAPT_XML_DOM_H 18 #define AAPT_XML_DOM_H 19 20 #include "Diagnostics.h" 21 #include "Resource.h" 22 #include "ResourceValues.h" 23 #include "util/StringPiece.h" 24 #include "util/Util.h" 25 #include "xml/XmlUtil.h" 26 27 #include <istream> 28 #include <memory> 29 #include <string> 30 #include <vector> 31 32 namespace aapt { 33 namespace xml { 34 35 struct RawVisitor; 36 37 /** 38 * Base class for all XML nodes. 39 */ 40 struct Node { 41 Node* parent = nullptr; 42 size_t lineNumber = 0; 43 size_t columnNumber = 0; 44 std::u16string comment; 45 std::vector<std::unique_ptr<Node>> children; 46 47 virtual ~Node() = default; 48 49 void addChild(std::unique_ptr<Node> child); 50 virtual void accept(RawVisitor* visitor) = 0; 51 }; 52 53 /** 54 * Base class that implements the visitor methods for a 55 * subclass of Node. 56 */ 57 template <typename Derived> 58 struct BaseNode : public Node { 59 virtual void accept(RawVisitor* visitor) override; 60 }; 61 62 /** 63 * A Namespace XML node. Can only have one child. 64 */ 65 struct Namespace : public BaseNode<Namespace> { 66 std::u16string namespacePrefix; 67 std::u16string namespaceUri; 68 }; 69 70 struct AaptAttribute { 71 Maybe<ResourceId> id; 72 aapt::Attribute attribute; 73 }; 74 75 /** 76 * An XML attribute. 77 */ 78 struct Attribute { 79 std::u16string namespaceUri; 80 std::u16string name; 81 std::u16string value; 82 83 Maybe<AaptAttribute> compiledAttribute; 84 std::unique_ptr<Item> compiledValue; 85 }; 86 87 /** 88 * An Element XML node. 89 */ 90 struct Element : public BaseNode<Element> { 91 std::u16string namespaceUri; 92 std::u16string name; 93 std::vector<Attribute> attributes; 94 95 Attribute* findAttribute(const StringPiece16& ns, const StringPiece16& name); 96 xml::Element* findChild(const StringPiece16& ns, const StringPiece16& name); 97 xml::Element* findChildWithAttribute(const StringPiece16& ns, const StringPiece16& name, 98 const StringPiece16& attrNs, 99 const StringPiece16& attrName, 100 const StringPiece16& attrValue); 101 std::vector<xml::Element*> getChildElements(); 102 }; 103 104 /** 105 * A Text (CDATA) XML node. Can not have any children. 106 */ 107 struct Text : public BaseNode<Text> { 108 std::u16string text; 109 }; 110 111 /** 112 * An XML resource with a source, name, and XML tree. 113 */ 114 struct XmlResource { 115 ResourceFile file; 116 std::unique_ptr<xml::Node> root; 117 }; 118 119 /** 120 * Inflates an XML DOM from a text stream, logging errors to the logger. 121 * Returns the root node on success, or nullptr on failure. 122 */ 123 std::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag, const Source& source); 124 125 /** 126 * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger. 127 * Returns the root node on success, or nullptr on failure. 128 */ 129 std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag, 130 const Source& source); 131 132 Element* findRootElement(XmlResource* doc); 133 Element* findRootElement(Node* node); 134 135 /** 136 * A visitor interface for the different XML Node subtypes. This will not traverse into 137 * children. Use Visitor for that. 138 */ 139 struct RawVisitor { 140 virtual ~RawVisitor() = default; 141 142 virtual void visit(Namespace* node) {} 143 virtual void visit(Element* node) {} 144 virtual void visit(Text* text) {} 145 }; 146 147 /** 148 * Visitor whose default implementation visits the children nodes of any node. 149 */ 150 struct Visitor : public RawVisitor { 151 using RawVisitor::visit; 152 153 void visit(Namespace* node) override { 154 visitChildren(node); 155 } 156 157 void visit(Element* node) override { 158 visitChildren(node); 159 } 160 161 void visit(Text* text) override { 162 visitChildren(text); 163 } 164 165 void visitChildren(Node* node) { 166 for (auto& child : node->children) { 167 child->accept(this); 168 } 169 } 170 }; 171 172 /** 173 * An XML DOM visitor that will record the package name for a namespace prefix. 174 */ 175 class PackageAwareVisitor : public Visitor, public IPackageDeclStack { 176 private: 177 struct PackageDecl { 178 std::u16string prefix; 179 ExtractedPackage package; 180 }; 181 182 std::vector<PackageDecl> mPackageDecls; 183 184 public: 185 using Visitor::visit; 186 187 void visit(Namespace* ns) override; 188 Maybe<ExtractedPackage> transformPackageAlias( 189 const StringPiece16& alias, const StringPiece16& localPackage) const override; 190 }; 191 192 // Implementations 193 194 template <typename Derived> 195 void BaseNode<Derived>::accept(RawVisitor* visitor) { 196 visitor->visit(static_cast<Derived*>(this)); 197 } 198 199 template <typename T> 200 struct NodeCastImpl : public RawVisitor { 201 using RawVisitor::visit; 202 203 T* value = nullptr; 204 205 void visit(T* v) override { 206 value = v; 207 } 208 }; 209 210 template <typename T> 211 T* nodeCast(Node* node) { 212 NodeCastImpl<T> visitor; 213 node->accept(&visitor); 214 return visitor.value; 215 } 216 217 } // namespace xml 218 } // namespace aapt 219 220 #endif // AAPT_XML_DOM_H 221