Home | History | Annotate | Download | only in xml
      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