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 <memory> 21 #include <string> 22 #include <vector> 23 24 #include "androidfw/StringPiece.h" 25 26 #include "Diagnostics.h" 27 #include "Resource.h" 28 #include "ResourceValues.h" 29 #include "io/Io.h" 30 #include "util/Util.h" 31 #include "xml/XmlUtil.h" 32 33 namespace aapt { 34 namespace xml { 35 36 class Element; 37 class Visitor; 38 class ConstVisitor; 39 40 // Base class for all XML nodes. 41 class Node { 42 public: 43 virtual ~Node() = default; 44 45 Element* parent = nullptr; 46 size_t line_number = 0u; 47 size_t column_number = 0u; 48 std::string comment; 49 50 virtual void Accept(Visitor* visitor) = 0; 51 virtual void Accept(ConstVisitor* visitor) const = 0; 52 53 using ElementCloneFunc = std::function<void(const Element&, Element*)>; 54 55 // Clones the Node subtree, using the given function to decide how to clone an Element. 56 virtual std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const = 0; 57 }; 58 59 // A namespace declaration (xmlns:prefix="uri"). 60 struct NamespaceDecl { 61 std::string prefix; 62 std::string uri; 63 size_t line_number = 0u; 64 size_t column_number = 0u; 65 }; 66 67 struct AaptAttribute { 68 explicit AaptAttribute(const ::aapt::Attribute& attr, const Maybe<ResourceId>& resid = {}) 69 : attribute(attr), id(resid) { 70 } 71 72 aapt::Attribute attribute; 73 Maybe<ResourceId> id; 74 }; 75 76 // An XML attribute. 77 struct Attribute { 78 std::string namespace_uri; 79 std::string name; 80 std::string value; 81 82 Maybe<AaptAttribute> compiled_attribute; 83 std::unique_ptr<Item> compiled_value; 84 }; 85 86 // An Element XML node. 87 class Element : public Node { 88 public: 89 // Ordered namespace prefix declarations. 90 std::vector<NamespaceDecl> namespace_decls; 91 92 std::string namespace_uri; 93 std::string name; 94 std::vector<Attribute> attributes; 95 std::vector<std::unique_ptr<Node>> children; 96 97 void AppendChild(std::unique_ptr<Node> child); 98 void InsertChild(size_t index, std::unique_ptr<Node> child); 99 100 Attribute* FindAttribute(const android::StringPiece& ns, const android::StringPiece& name); 101 const Attribute* FindAttribute(const android::StringPiece& ns, 102 const android::StringPiece& name) const; 103 Attribute* FindOrCreateAttribute(const android::StringPiece& ns, 104 const android::StringPiece& name); 105 106 Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name); 107 const Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name) const; 108 109 Element* FindChildWithAttribute(const android::StringPiece& ns, const android::StringPiece& name, 110 const android::StringPiece& attr_ns, 111 const android::StringPiece& attr_name, 112 const android::StringPiece& attr_value); 113 114 const Element* FindChildWithAttribute(const android::StringPiece& ns, 115 const android::StringPiece& name, 116 const android::StringPiece& attr_ns, 117 const android::StringPiece& attr_name, 118 const android::StringPiece& attr_value) const; 119 120 std::vector<Element*> GetChildElements(); 121 122 // Due to overriding of subtypes not working with unique_ptr, define a convenience Clone method 123 // that knows cloning an element returns an element. 124 std::unique_ptr<Element> CloneElement(const ElementCloneFunc& el_cloner) const; 125 126 std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const override; 127 128 void Accept(Visitor* visitor) override; 129 void Accept(ConstVisitor* visitor) const override; 130 }; 131 132 // A Text (CDATA) XML node. Can not have any children. 133 class Text : public Node { 134 public: 135 std::string text; 136 137 std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const override; 138 139 void Accept(Visitor* visitor) override; 140 void Accept(ConstVisitor* visitor) const override; 141 }; 142 143 // An XML resource with a source, name, and XML tree. 144 class XmlResource { 145 public: 146 ResourceFile file; 147 148 // StringPool must come before the xml::Node. Destructors are called in reverse order, and 149 // the xml::Node may have StringPool references that need to be destroyed before the StringPool 150 // is destroyed. 151 StringPool string_pool; 152 153 std::unique_ptr<xml::Element> root; 154 155 std::unique_ptr<XmlResource> Clone() const; 156 }; 157 158 // Inflates an XML DOM from an InputStream, logging errors to the logger. 159 std::unique_ptr<XmlResource> Inflate(io::InputStream* in, IDiagnostics* diag, const Source& source); 160 161 // Inflates an XML DOM from a binary ResXMLTree. 162 std::unique_ptr<XmlResource> Inflate(const void* data, size_t len, 163 std::string* out_error = nullptr); 164 165 Element* FindRootElement(Node* node); 166 167 // Visitor whose default implementation visits the children nodes of any node. 168 class Visitor { 169 public: 170 virtual ~Visitor() = default; 171 172 virtual void Visit(Element* el) { 173 VisitChildren(el); 174 } 175 176 virtual void Visit(Text* text) { 177 } 178 179 protected: 180 Visitor() = default; 181 182 void VisitChildren(Element* el) { 183 for (auto& child : el->children) { 184 child->Accept(this); 185 } 186 } 187 188 virtual void BeforeVisitElement(Element* el) { 189 } 190 virtual void AfterVisitElement(Element* el) { 191 } 192 193 private: 194 DISALLOW_COPY_AND_ASSIGN(Visitor); 195 196 friend class Element; 197 }; 198 199 class ConstVisitor { 200 public: 201 virtual ~ConstVisitor() = default; 202 203 virtual void Visit(const Element* el) { 204 VisitChildren(el); 205 } 206 207 virtual void Visit(const Text* text) { 208 } 209 210 protected: 211 ConstVisitor() = default; 212 213 void VisitChildren(const Element* el) { 214 for (const auto& child : el->children) { 215 child->Accept(this); 216 } 217 } 218 219 virtual void BeforeVisitElement(const Element* el) { 220 } 221 222 virtual void AfterVisitElement(const Element* el) { 223 } 224 225 private: 226 DISALLOW_COPY_AND_ASSIGN(ConstVisitor); 227 228 friend class Element; 229 }; 230 231 // An XML DOM visitor that will record the package name for a namespace prefix. 232 class PackageAwareVisitor : public Visitor, public IPackageDeclStack { 233 public: 234 using Visitor::Visit; 235 236 Maybe<ExtractedPackage> TransformPackageAlias(const android::StringPiece& alias) const override; 237 238 protected: 239 PackageAwareVisitor() = default; 240 241 void BeforeVisitElement(Element* el) override; 242 void AfterVisitElement(Element* el) override; 243 244 private: 245 DISALLOW_COPY_AND_ASSIGN(PackageAwareVisitor); 246 247 struct PackageDecl { 248 std::string prefix; 249 ExtractedPackage package; 250 }; 251 252 std::vector<std::vector<PackageDecl>> package_decls_; 253 }; 254 255 namespace internal { 256 257 // Base class that overrides the default behaviour and does not descend into child nodes. 258 class NodeCastBase : public ConstVisitor { 259 public: 260 void Visit(const Element* el) override { 261 } 262 void Visit(const Text* el) override { 263 } 264 265 protected: 266 NodeCastBase() = default; 267 268 void BeforeVisitElement(const Element* el) override { 269 } 270 void AfterVisitElement(const Element* el) override { 271 } 272 273 private: 274 DISALLOW_COPY_AND_ASSIGN(NodeCastBase); 275 }; 276 277 template <typename T> 278 class NodeCastImpl : public NodeCastBase { 279 public: 280 using NodeCastBase::Visit; 281 282 NodeCastImpl() = default; 283 284 const T* value = nullptr; 285 286 void Visit(const T* v) override { 287 value = v; 288 } 289 290 private: 291 DISALLOW_COPY_AND_ASSIGN(NodeCastImpl); 292 }; 293 294 } // namespace internal 295 296 template <typename T> 297 const T* NodeCast(const Node* node) { 298 internal::NodeCastImpl<T> visitor; 299 node->Accept(&visitor); 300 return visitor.value; 301 } 302 303 template <typename T> 304 T* NodeCast(Node* node) { 305 return const_cast<T*>(NodeCast<T>(static_cast<const T*>(node))); 306 } 307 308 } // namespace xml 309 } // namespace aapt 310 311 #endif // AAPT_XML_DOM_H 312