Home | History | Annotate | Download | only in xml
      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