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 = {})
attributeAaptAttribute86       : 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 
Visit(Namespace * node)177   virtual void Visit(Namespace* node) {}
Visit(Element * node)178   virtual void Visit(Element* node) {}
Visit(Text * text)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 
Visit(Namespace * node)189   void Visit(Namespace* node) override { VisitChildren(node); }
190 
Visit(Element * node)191   void Visit(Element* node) override { VisitChildren(node); }
192 
Visit(Text * text)193   void Visit(Text* text) override { VisitChildren(text); }
194 
VisitChildren(Node * node)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>
Accept(RawVisitor * visitor)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 
Visit(T * v)236   void Visit(T* v) override { value = v; }
237 };
238 
239 template <typename T>
NodeCast(Node * node)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