[go: nahoru, domu]

175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/*
275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Copyright (C) 2015 The Android Open Source Project
375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski *
475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * you may not use this file except in compliance with the License.
675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * You may obtain a copy of the License at
775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski *
875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski *
1075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Unless required by applicable law or agreed to in writing, software
1175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
1275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * See the License for the specific language governing permissions and
1475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * limitations under the License.
1575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
1675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
1775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#ifndef AAPT_XML_DOM_H
1875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#define AAPT_XML_DOM_H
1975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Diagnostics.h"
211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Resource.h"
221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ResourceValues.h"
231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/StringPiece.h"
241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h"
25467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "xml/XmlUtil.h"
2675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
2775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <istream>
2875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <memory>
2975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <string>
3075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <vector>
3175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
3275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace aapt {
3375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace xml {
3475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct RawVisitor;
3675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
3775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
3875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Base class for all XML nodes.
3975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
4075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Node {
411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    Node* parent = nullptr;
421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    size_t lineNumber = 0;
431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    size_t columnNumber = 0;
4475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string comment;
4575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::vector<std::unique_ptr<Node>> children;
4675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
47467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    virtual ~Node() = default;
48467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski
4975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    void addChild(std::unique_ptr<Node> child);
501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    virtual void accept(RawVisitor* visitor) = 0;
5175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
5275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
5375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
5475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Base class that implements the visitor methods for a
5575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * subclass of Node.
5675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
5775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskitemplate <typename Derived>
5875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct BaseNode : public Node {
591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    virtual void accept(RawVisitor* visitor) override;
6075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
6175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
6275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
6375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * A Namespace XML node. Can only have one child.
6475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
6575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Namespace : public BaseNode<Namespace> {
6675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string namespacePrefix;
6775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string namespaceUri;
681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
6975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct AaptAttribute {
7164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    Maybe<ResourceId> id;
721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    aapt::Attribute attribute;
7375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
7475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
7575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
7675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * An XML attribute.
7775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
7875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Attribute {
7975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string namespaceUri;
8075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string name;
8175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string value;
821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    Maybe<AaptAttribute> compiledAttribute;
841ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    std::unique_ptr<Item> compiledValue;
8575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
8675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
8775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
8875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * An Element XML node.
8975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
9075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Element : public BaseNode<Element> {
9175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string namespaceUri;
9275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string name;
9375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::vector<Attribute> attributes;
9475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
9575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    Attribute* findAttribute(const StringPiece16& ns, const StringPiece16& name);
9675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    xml::Element* findChild(const StringPiece16& ns, const StringPiece16& name);
9775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    xml::Element* findChildWithAttribute(const StringPiece16& ns, const StringPiece16& name,
981ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski                                         const StringPiece16& attrNs,
991ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski                                         const StringPiece16& attrName,
1001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski                                         const StringPiece16& attrValue);
10175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::vector<xml::Element*> getChildElements();
10275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
10375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
10475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
10575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * A Text (CDATA) XML node. Can not have any children.
10675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
10775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Text : public BaseNode<Text> {
10875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski    std::u16string text;
10975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
11075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
11175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
112467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski * An XML resource with a source, name, and XML tree.
113467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski */
114467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinskistruct XmlResource {
115467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    ResourceFile file;
116467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    std::unique_ptr<xml::Node> root;
117467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski};
118467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski
119467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski/**
12075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Inflates an XML DOM from a text stream, logging errors to the logger.
12175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Returns the root node on success, or nullptr on failure.
12275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
1231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistd::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag, const Source& source);
12475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
12575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
12675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger.
12775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Returns the root node on success, or nullptr on failure.
12875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
1291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistd::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag,
1301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski                                     const Source& source);
1311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
132467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam LesinskiElement* findRootElement(XmlResource* doc);
133ca5638fd85098c3d0a699492751043545f75553aAdam LesinskiElement* findRootElement(Node* node);
134ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
1351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/**
1361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * A visitor interface for the different XML Node subtypes. This will not traverse into
1371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * children. Use Visitor for that.
1381ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
1391ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct RawVisitor {
1401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    virtual ~RawVisitor() = default;
1411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    virtual void visit(Namespace* node) {}
1431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    virtual void visit(Element* node) {}
1441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    virtual void visit(Text* text) {}
1451ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
1461ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/**
1481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Visitor whose default implementation visits the children nodes of any node.
1491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
1501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct Visitor : public RawVisitor {
1511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    using RawVisitor::visit;
1521ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1531ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    void visit(Namespace* node) override {
1541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        visitChildren(node);
1551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
1561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1571ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    void visit(Element* node) override {
1581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        visitChildren(node);
1591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
1601ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1611ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    void visit(Text* text) override {
1621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        visitChildren(text);
1631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
1641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    void visitChildren(Node* node) {
1661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        for (auto& child : node->children) {
1671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            child->accept(this);
1681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        }
1691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
1701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
17175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
17275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/**
1731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * An XML DOM visitor that will record the package name for a namespace prefix.
17475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */
1751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass PackageAwareVisitor : public Visitor, public IPackageDeclStack {
1761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiprivate:
1771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    struct PackageDecl {
1781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        std::u16string prefix;
179467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski        ExtractedPackage package;
1801ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    };
1811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    std::vector<PackageDecl> mPackageDecls;
1831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1841ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskipublic:
1851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    using Visitor::visit;
1861ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
187467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    void visit(Namespace* ns) override;
188467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    Maybe<ExtractedPackage> transformPackageAlias(
189467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski            const StringPiece16& alias, const StringPiece16& localPackage) const override;
19075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski};
19175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
19275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski// Implementations
19375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
19475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskitemplate <typename Derived>
1951ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid BaseNode<Derived>::accept(RawVisitor* visitor) {
1961ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    visitor->visit(static_cast<Derived*>(this));
19775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}
19875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
1991ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T>
2001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct NodeCastImpl : public RawVisitor {
2011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    using RawVisitor::visit;
2021ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
2031ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    T* value = nullptr;
2041ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
2051ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    void visit(T* v) override {
2061ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        value = v;
2071ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
2081ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
2091ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
2101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T>
2111ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiT* nodeCast(Node* node) {
2121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    NodeCastImpl<T> visitor;
2131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    node->accept(&visitor);
2141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    return visitor.value;
21575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}
21675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
21775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} // namespace xml
21875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} // namespace aapt
21975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski
22075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#endif // AAPT_XML_DOM_H
221