1 /*
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 #ifndef AAPT_XML_XMLPATTERN_H
18 #define AAPT_XML_XMLPATTERN_H
19 
20 #include "Diagnostics.h"
21 #include "xml/XmlDom.h"
22 
23 #include <android-base/macros.h>
24 #include <functional>
25 #include <map>
26 #include <string>
27 #include <vector>
28 
29 namespace aapt {
30 namespace xml {
31 
32 enum class XmlActionExecutorPolicy {
33     /**
34      * Actions on run if elements are matched, errors occur only when actions return false.
35      */
36     None,
37 
38     /**
39      * The actions defined must match and run. If an element is found that does not match
40      * an action, an error occurs.
41      */
42     Whitelist,
43 };
44 
45 /**
46  * Contains the actions to perform at this XML node. This is a recursive data structure that
47  * holds XmlNodeActions for child XML nodes.
48  */
49 class XmlNodeAction {
50 public:
51     using ActionFuncWithDiag = std::function<bool(Element*, SourcePathDiagnostics*)>;
52     using ActionFunc = std::function<bool(Element*)>;
53 
54     /**
55      * Find or create a child XmlNodeAction that will be performed for the child element
56      * with the name `name`.
57      */
58     XmlNodeAction& operator[](const std::u16string& name) {
59         return mMap[name];
60     }
61 
62     /**
63      * Add an action to be performed at this XmlNodeAction.
64      */
65     void action(ActionFunc f);
66     void action(ActionFuncWithDiag);
67 
68 private:
69     friend class XmlActionExecutor;
70 
71     bool execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag, Element* el) const;
72 
73     std::map<std::u16string, XmlNodeAction> mMap;
74     std::vector<ActionFuncWithDiag> mActions;
75 };
76 
77 /**
78  * Allows the definition of actions to execute at specific XML elements defined by their
79  * hierarchy.
80  */
81 class XmlActionExecutor {
82 public:
83     XmlActionExecutor() = default;
84 
85     /**
86      * Find or create a root XmlNodeAction that will be performed for the root XML element
87      * with the name `name`.
88      */
89     XmlNodeAction& operator[](const std::u16string& name) {
90         return mMap[name];
91     }
92 
93     /**
94      * Execute the defined actions for this XmlResource.
95      * Returns true if all actions return true, otherwise returns false.
96      */
97     bool execute(XmlActionExecutorPolicy policy, IDiagnostics* diag, XmlResource* doc) const;
98 
99 private:
100     std::map<std::u16string, XmlNodeAction> mMap;
101 
102     DISALLOW_COPY_AND_ASSIGN(XmlActionExecutor);
103 };
104 
105 } // namespace xml
106 } // namespace aapt
107 
108 #endif /* AAPT_XML_XMLPATTERN_H */
109