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 33 namespace aapt { 34 namespace xml { 35 36 class RawVisitor; 37 38 class Element; 39 40 /** 41 * Base class for all XML nodes. 42 */ 43 class 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 */ 67 template <typename Derived> 68 class 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 */ 76 class 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 84 struct 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 */ 96 struct 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 */ 108 class 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 */ 130 class 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 */ 140 class 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 */ 156 std::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 */ 162 std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, IDiagnostics* diag, 163 const Source& source); 164 165 Element* FindRootElement(XmlResource* doc); 166 Element* 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 */ 173 class 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 */ 185 class 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 */ 205 class 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 224 template <typename Derived> 225 void BaseNode<Derived>::Accept(RawVisitor* visitor) { 226 visitor->Visit(static_cast<Derived*>(this)); 227 } 228 229 template <typename T> 230 class 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 239 template <typename T> 240 T* 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