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 <istream> 21#include <memory> 22#include <string> 23#include <vector> 24 25#include "androidfw/StringPiece.h" 26 27#include "Diagnostics.h" 28#include "Resource.h" 29#include "ResourceValues.h" 30#include "util/Util.h" 31#include "xml/XmlUtil.h" 32 33namespace aapt { 34namespace xml { 35 36class RawVisitor; 37 38class Element; 39 40/** 41 * Base class for all XML nodes. 42 */ 43class Node { 44 public: 45 Node* parent = nullptr; 46 size_t line_number = 0; 47 size_t column_number = 0; 48 std::string comment; 49 std::vector<std::unique_ptr<Node>> children; 50 51 virtual ~Node() = default; 52 53 void AppendChild(std::unique_ptr<Node> child); 54 void InsertChild(size_t index, std::unique_ptr<Node> child); 55 virtual void Accept(RawVisitor* visitor) = 0; 56 57 using ElementCloneFunc = std::function<void(const Element&, Element*)>; 58 59 // Clones the Node subtree, using the given function to decide how to clone an Element. 60 virtual std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) = 0; 61}; 62 63/** 64 * Base class that implements the visitor methods for a 65 * subclass of Node. 66 */ 67template <typename Derived> 68class BaseNode : public Node { 69 public: 70 virtual void Accept(RawVisitor* visitor) override; 71}; 72 73/** 74 * A Namespace XML node. Can only have one child. 75 */ 76class Namespace : public BaseNode<Namespace> { 77 public: 78 std::string namespace_prefix; 79 std::string namespace_uri; 80 81 std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) override; 82}; 83 84struct AaptAttribute { 85 explicit AaptAttribute(const ::aapt::Attribute& attr, const Maybe<ResourceId>& resid = {}) 86 : attribute(attr), id(resid) { 87 } 88 89 aapt::Attribute attribute; 90 Maybe<ResourceId> id; 91}; 92 93/** 94 * An XML attribute. 95 */ 96struct Attribute { 97 std::string namespace_uri; 98 std::string name; 99 std::string value; 100 101 Maybe<AaptAttribute> compiled_attribute; 102 std::unique_ptr<Item> compiled_value; 103}; 104 105/** 106 * An Element XML node. 107 */ 108class Element : public BaseNode<Element> { 109 public: 110 std::string namespace_uri; 111 std::string name; 112 std::vector<Attribute> attributes; 113 114 Attribute* FindAttribute(const android::StringPiece& ns, const android::StringPiece& name); 115 const Attribute* FindAttribute(const android::StringPiece& ns, 116 const android::StringPiece& name) const; 117 xml::Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name); 118 xml::Element* FindChildWithAttribute(const android::StringPiece& ns, 119 const android::StringPiece& name, 120 const android::StringPiece& attr_ns, 121 const android::StringPiece& attr_name, 122 const android::StringPiece& attr_value); 123 std::vector<xml::Element*> GetChildElements(); 124 std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) override; 125}; 126 127/** 128 * A Text (CDATA) XML node. Can not have any children. 129 */ 130class Text : public BaseNode<Text> { 131 public: 132 std::string text; 133 134 std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) override; 135}; 136 137/** 138 * An XML resource with a source, name, and XML tree. 139 */ 140class XmlResource { 141 public: 142 ResourceFile file; 143 144 // StringPool must come before the xml::Node. Destructors are called in reverse order, and 145 // the xml::Node may have StringPool references that need to be destroyed before the StringPool 146 // is destroyed. 147 StringPool string_pool; 148 149 std::unique_ptr<xml::Node> root; 150}; 151 152/** 153 * Inflates an XML DOM from a text stream, logging errors to the logger. 154 * Returns the root node on success, or nullptr on failure. 155 */ 156std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag, const Source& source); 157 158/** 159 * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger. 160 * Returns the root node on success, or nullptr on failure. 161 */ 162std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, IDiagnostics* diag, 163 const Source& source); 164 165Element* FindRootElement(XmlResource* doc); 166Element* FindRootElement(Node* node); 167 168/** 169 * A visitor interface for the different XML Node subtypes. This will not 170 * traverse into 171 * children. Use Visitor for that. 172 */ 173class RawVisitor { 174 public: 175 virtual ~RawVisitor() = default; 176 177 virtual void Visit(Namespace* node) {} 178 virtual void Visit(Element* node) {} 179 virtual void Visit(Text* text) {} 180}; 181 182/** 183 * Visitor whose default implementation visits the children nodes of any node. 184 */ 185class Visitor : public RawVisitor { 186 public: 187 using RawVisitor::Visit; 188 189 void Visit(Namespace* node) override { VisitChildren(node); } 190 191 void Visit(Element* node) override { VisitChildren(node); } 192 193 void Visit(Text* text) override { VisitChildren(text); } 194 195 void VisitChildren(Node* node) { 196 for (auto& child : node->children) { 197 child->Accept(this); 198 } 199 } 200}; 201 202/** 203 * An XML DOM visitor that will record the package name for a namespace prefix. 204 */ 205class PackageAwareVisitor : public Visitor, public IPackageDeclStack { 206 public: 207 using Visitor::Visit; 208 209 void Visit(Namespace* ns) override; 210 Maybe<ExtractedPackage> TransformPackageAlias( 211 const android::StringPiece& alias, const android::StringPiece& local_package) const override; 212 213 private: 214 struct PackageDecl { 215 std::string prefix; 216 ExtractedPackage package; 217 }; 218 219 std::vector<PackageDecl> package_decls_; 220}; 221 222// Implementations 223 224template <typename Derived> 225void BaseNode<Derived>::Accept(RawVisitor* visitor) { 226 visitor->Visit(static_cast<Derived*>(this)); 227} 228 229template <typename T> 230class NodeCastImpl : public RawVisitor { 231 public: 232 using RawVisitor::Visit; 233 234 T* value = nullptr; 235 236 void Visit(T* v) override { value = v; } 237}; 238 239template <typename T> 240T* NodeCast(Node* node) { 241 NodeCastImpl<T> visitor; 242 node->Accept(&visitor); 243 return visitor.value; 244} 245 246} // namespace xml 247} // namespace aapt 248 249#endif // AAPT_XML_DOM_H 250