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