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