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 void RemoveAttribute(const android::StringPiece& ns, 106 const android::StringPiece& name); 107 108 Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name); 109 const Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name) const; 110 111 Element* FindChildWithAttribute(const android::StringPiece& ns, const android::StringPiece& name, 112 const android::StringPiece& attr_ns, 113 const android::StringPiece& attr_name, 114 const android::StringPiece& attr_value); 115 116 const Element* FindChildWithAttribute(const android::StringPiece& ns, 117 const android::StringPiece& name, 118 const android::StringPiece& attr_ns, 119 const android::StringPiece& attr_name, 120 const android::StringPiece& attr_value) const; 121 122 std::vector<Element*> GetChildElements(); 123 124 // Due to overriding of subtypes not working with unique_ptr, define a convenience Clone method 125 // that knows cloning an element returns an element. 126 std::unique_ptr<Element> CloneElement(const ElementCloneFunc& el_cloner) const; 127 128 std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const override; 129 130 void Accept(Visitor* visitor) override; 131 void Accept(ConstVisitor* visitor) const override; 132 }; 133 134 // A Text (CDATA) XML node. Can not have any children. 135 class Text : public Node { 136 public: 137 std::string text; 138 139 std::unique_ptr<Node> Clone(const ElementCloneFunc& el_cloner) const override; 140 141 void Accept(Visitor* visitor) override; 142 void Accept(ConstVisitor* visitor) const override; 143 }; 144 145 // An XML resource with a source, name, and XML tree. 146 class XmlResource { 147 public: 148 ResourceFile file; 149 150 // StringPool must come before the xml::Node. Destructors are called in reverse order, and 151 // the xml::Node may have StringPool references that need to be destroyed before the StringPool 152 // is destroyed. 153 StringPool string_pool; 154 155 std::unique_ptr<xml::Element> root; 156 157 std::unique_ptr<XmlResource> Clone() const; 158 }; 159 160 // Inflates an XML DOM from an InputStream, logging errors to the logger. 161 std::unique_ptr<XmlResource> Inflate(io::InputStream* in, IDiagnostics* diag, const Source& source); 162 163 // Inflates an XML DOM from a binary ResXMLTree. 164 std::unique_ptr<XmlResource> Inflate(const void* data, size_t len, 165 std::string* out_error = nullptr); 166 167 Element* FindRootElement(Node* node); 168 169 // Visitor whose default implementation visits the children nodes of any node. 170 class Visitor { 171 public: 172 virtual ~Visitor() = default; 173 174 virtual void Visit(Element* el) { 175 VisitChildren(el); 176 } 177 178 virtual void Visit(Text* text) { 179 } 180 181 protected: 182 Visitor() = default; 183 184 void VisitChildren(Element* el) { 185 for (auto& child : el->children) { 186 child->Accept(this); 187 } 188 } 189 190 virtual void BeforeVisitElement(Element* el) { 191 } 192 virtual void AfterVisitElement(Element* el) { 193 } 194 195 private: 196 DISALLOW_COPY_AND_ASSIGN(Visitor); 197 198 friend class Element; 199 }; 200 201 class ConstVisitor { 202 public: 203 virtual ~ConstVisitor() = default; 204 205 virtual void Visit(const Element* el) { 206 VisitChildren(el); 207 } 208 209 virtual void Visit(const Text* text) { 210 } 211 212 protected: 213 ConstVisitor() = default; 214 215 void VisitChildren(const Element* el) { 216 for (const auto& child : el->children) { 217 child->Accept(this); 218 } 219 } 220 221 virtual void BeforeVisitElement(const Element* el) { 222 } 223 224 virtual void AfterVisitElement(const Element* el) { 225 } 226 227 private: 228 DISALLOW_COPY_AND_ASSIGN(ConstVisitor); 229 230 friend class Element; 231 }; 232 233 // An XML DOM visitor that will record the package name for a namespace prefix. 234 class PackageAwareVisitor : public Visitor, public IPackageDeclStack { 235 public: 236 using Visitor::Visit; 237 238 Maybe<ExtractedPackage> TransformPackageAlias(const android::StringPiece& alias) const override; 239 240 protected: 241 PackageAwareVisitor() = default; 242 243 void BeforeVisitElement(Element* el) override; 244 void AfterVisitElement(Element* el) override; 245 246 private: 247 DISALLOW_COPY_AND_ASSIGN(PackageAwareVisitor); 248 249 struct PackageDecl { 250 std::string prefix; 251 ExtractedPackage package; 252 }; 253 254 std::vector<std::vector<PackageDecl>> package_decls_; 255 }; 256 257 namespace internal { 258 259 // Base class that overrides the default behaviour and does not descend into child nodes. 260 class NodeCastBase : public ConstVisitor { 261 public: 262 void Visit(const Element* el) override { 263 } 264 void Visit(const Text* el) override { 265 } 266 267 protected: 268 NodeCastBase() = default; 269 270 void BeforeVisitElement(const Element* el) override { 271 } 272 void AfterVisitElement(const Element* el) override { 273 } 274 275 private: 276 DISALLOW_COPY_AND_ASSIGN(NodeCastBase); 277 }; 278 279 template <typename T> 280 class NodeCastImpl : public NodeCastBase { 281 public: 282 using NodeCastBase::Visit; 283 284 NodeCastImpl() = default; 285 286 const T* value = nullptr; 287 288 void Visit(const T* v) override { 289 value = v; 290 } 291 292 private: 293 DISALLOW_COPY_AND_ASSIGN(NodeCastImpl); 294 }; 295 296 } // namespace internal 297 298 template <typename T> 299 const T* NodeCast(const Node* node) { 300 internal::NodeCastImpl<T> visitor; 301 node->Accept(&visitor); 302 return visitor.value; 303 } 304 305 template <typename T> 306 T* NodeCast(Node* node) { 307 return const_cast<T*>(NodeCast<T>(static_cast<const T*>(node))); 308 } 309 310 } // namespace xml 311 } // namespace aapt 312 313 #endif // AAPT_XML_DOM_H 314