blob: 745079c43c7c1c6b44be5013e2e4bb0e7d86bfce [file] [log] [blame]
Adam Lesinskicc5609d2016-04-05 12:41:07 -07001/*
2 * Copyright (C) 2016 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#include "xml/XmlActionExecutor.h"
18
19namespace aapt {
20namespace xml {
21
22static bool wrapperOne(XmlNodeAction::ActionFunc& f, Element* el, SourcePathDiagnostics*) {
23 return f(el);
24}
25
26static bool wrapperTwo(XmlNodeAction::ActionFuncWithDiag& f, Element* el,
27 SourcePathDiagnostics* diag) {
28 return f(el, diag);
29}
30
31void XmlNodeAction::action(XmlNodeAction::ActionFunc f) {
32 mActions.emplace_back(std::bind(wrapperOne, std::move(f),
33 std::placeholders::_1,
34 std::placeholders::_2));
35}
36
37void XmlNodeAction::action(XmlNodeAction::ActionFuncWithDiag f) {
38 mActions.emplace_back(std::bind(wrapperTwo, std::move(f),
39 std::placeholders::_1,
40 std::placeholders::_2));
41}
42
43static void printElementToDiagMessage(const Element* el, DiagMessage* msg) {
44 *msg << "<";
45 if (!el->namespaceUri.empty()) {
46 *msg << el->namespaceUri << ":";
47 }
48 *msg << el->name << ">";
49}
50
51bool XmlNodeAction::execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag,
52 Element* el) const {
53 bool error = false;
54 for (const ActionFuncWithDiag& action : mActions) {
55 error |= !action(el, diag);
56 }
57
58 for (Element* childEl : el->getChildElements()) {
59 if (childEl->namespaceUri.empty()) {
Adam Lesinskid0f116b2016-07-08 15:00:32 -070060 std::map<std::string, XmlNodeAction>::const_iterator iter = mMap.find(childEl->name);
Adam Lesinskicc5609d2016-04-05 12:41:07 -070061 if (iter != mMap.end()) {
62 error |= !iter->second.execute(policy, diag, childEl);
63 continue;
64 }
65 }
66
67 if (policy == XmlActionExecutorPolicy::Whitelist) {
68 DiagMessage errorMsg(childEl->lineNumber);
69 errorMsg << "unknown element ";
70 printElementToDiagMessage(childEl, &errorMsg);
71 errorMsg << " found";
72 diag->error(errorMsg);
73 error = true;
74 }
75 }
76 return !error;
77}
78
79bool XmlActionExecutor::execute(XmlActionExecutorPolicy policy, IDiagnostics* diag,
80 XmlResource* doc) const {
81 SourcePathDiagnostics sourceDiag(doc->file.source, diag);
82
83 Element* el = findRootElement(doc);
84 if (!el) {
85 if (policy == XmlActionExecutorPolicy::Whitelist) {
86 sourceDiag.error(DiagMessage() << "no root XML tag found");
87 return false;
88 }
89 return true;
90 }
91
92 if (el->namespaceUri.empty()) {
Adam Lesinskid0f116b2016-07-08 15:00:32 -070093 std::map<std::string, XmlNodeAction>::const_iterator iter = mMap.find(el->name);
Adam Lesinskicc5609d2016-04-05 12:41:07 -070094 if (iter != mMap.end()) {
95 return iter->second.execute(policy, &sourceDiag, el);
96 }
97 }
98
99 if (policy == XmlActionExecutorPolicy::Whitelist) {
100 DiagMessage errorMsg(el->lineNumber);
101 errorMsg << "unknown element ";
102 printElementToDiagMessage(el, &errorMsg);
103 errorMsg << " found";
104 sourceDiag.error(errorMsg);
105 return false;
106 }
107 return true;
108}
109
110} // namespace xml
111} // namespace aapt