4fe67b357fd27a4ecde4183dc28d795dfef676fc
[policy/apex-pdp.git] / auth / cli-editor / src / main / java / org / onap / policy / apex / auth / clieditor / KeywordNode.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.auth.clieditor;
23
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.NavigableMap;
27 import java.util.Set;
28 import java.util.TreeMap;
29 import java.util.TreeSet;
30
31 import org.onap.policy.common.utils.validation.Assertions;
32
33 /**
34  * The Class KeywordNode holds the structure of a command keyword for the Apex CLI editor. The
35  * keyword itself and all its children are held as a recursive tree. This class is used to manage
36  * interactive sub-modes in the Apex CLI editor.
37  */
38 public class KeywordNode implements Comparable<KeywordNode> {
39     private final String keyword;
40     private final TreeMap<String, KeywordNode> children;
41     private CommandLineCommand command;
42
43     /**
44      * This Constructor creates a keyword node with the given keyword and no command.
45      *
46      * @param keyword the keyword of the node
47      */
48     public KeywordNode(final String keyword) {
49         this(keyword, null);
50     }
51
52     /**
53      * This Constructor creates a keyword node with the given keyword and command.
54      *
55      * @param keyword the keyword of the keyword node
56      * @param command the command associated with this keyword
57      */
58     public KeywordNode(final String keyword, final CommandLineCommand command) {
59         Assertions.argumentNotNull(keyword, "commands may not be null");
60
61         this.keyword = keyword;
62         children = new TreeMap<>();
63         this.command = command;
64     }
65
66     /**
67      * Process a list of keywords on this keyword node, recursing the keyword node tree, creating
68      * new branches for the keyword list if required. When the end of a branch has been reached,
69      * store the command in that keyword node..
70      *
71      * @param keywordList the list of keywords to process on this keyword node
72      * @param incomingCommand the command
73      */
74     public void processKeywords(final List<String> keywordList, final CommandLineCommand incomingCommand) {
75         if (keywordList.isEmpty()) {
76             this.command = incomingCommand;
77             return;
78         }
79
80         if (!children.containsKey(keywordList.get(0))) {
81             children.put(keywordList.get(0), new KeywordNode(keywordList.get(0)));
82         }
83
84         final ArrayList<String> nextLevelKeywordList = new ArrayList<>(keywordList);
85         nextLevelKeywordList.remove(0);
86         children.get(keywordList.get(0)).processKeywords(nextLevelKeywordList, incomingCommand);
87     }
88
89     /**
90      * Adds the system commands to the keyword node.
91      *
92      * @param systemCommandNodes the system command nodes to add to the keyword node
93      */
94     public void addSystemCommandNodes(final Set<KeywordNode> systemCommandNodes) {
95         if (children.isEmpty()) {
96             return;
97         }
98
99         for (final KeywordNode node : children.values()) {
100             node.addSystemCommandNodes(systemCommandNodes);
101         }
102
103         for (final KeywordNode systemCommandNode : systemCommandNodes) {
104             children.put(systemCommandNode.getKeyword(), systemCommandNode);
105         }
106
107     }
108
109     /**
110      * Gets the keyword of this keyword node.
111      *
112      * @return the keyword of this keyword node
113      */
114     public String getKeyword() {
115         return keyword;
116     }
117
118     /**
119      * Gets the children of this keyword node.
120      *
121      * @return the children of this keyword node
122      */
123     public NavigableMap<String, KeywordNode> getChildren() {
124         return children;
125     }
126
127     /**
128      * Gets the command of this keyword node.
129      *
130      * @return the command of this keyword node
131      */
132     public CommandLineCommand getCommand() {
133         return command;
134     }
135
136     /**
137      * {@inheritDoc}.
138      */
139     @Override
140     public String toString() {
141         return "CommandKeywordNode [keyword=" + keyword + ", children=" + children + ", command=" + command + "]";
142     }
143
144     /**
145      * Gets the commands.
146      *
147      * @return the commands
148      */
149     public Set<CommandLineCommand> getCommands() {
150         final Set<CommandLineCommand> commandSet = new TreeSet<>();
151
152         for (final KeywordNode child : children.values()) {
153             if (child.getCommand() != null) {
154                 commandSet.add(child.getCommand());
155             }
156             commandSet.addAll(child.getCommands());
157         }
158
159         return commandSet;
160     }
161
162     /**
163      * {@inheritDoc}.
164      */
165     @Override
166     public int compareTo(final KeywordNode otherKeywordNode) {
167         Assertions.argumentNotNull(otherKeywordNode, "comparison object may not be null");
168
169         if (this == otherKeywordNode) {
170             return 0;
171         }
172         if (getClass() != otherKeywordNode.getClass()) {
173             return this.hashCode() - otherKeywordNode.hashCode();
174         }
175
176         final KeywordNode other = otherKeywordNode;
177
178         if (!keyword.equals(other.keyword)) {
179             return keyword.compareTo(other.keyword);
180         }
181         if (!children.equals(other.children)) {
182             return (children.hashCode() - other.children.hashCode());
183         }
184         return command.compareTo(otherKeywordNode.command);
185     }
186
187     @Override
188     public int hashCode() {
189         final int prime = 31;
190         int result = 1;
191         result = prime * result + ((children == null) ? 0 : children.hashCode());
192         result = prime * result + ((command == null) ? 0 : command.hashCode());
193         result = prime * result + ((keyword == null) ? 0 : keyword.hashCode());
194         return result;
195     }
196
197     @Override
198     public boolean equals(Object obj) {
199         if (this == obj) {
200             return true;
201         }
202
203         if (obj == null) {
204             return false;
205         }
206
207         if (getClass() != obj.getClass()) {
208             return false;
209         }
210
211         return this.compareTo((KeywordNode) obj) == 0;
212     }
213 }