blob: 7aae7679222ca73d5c5816d4d16e08077eac6d0a [file] [log] [blame]
Bharat saraswalab4c6ba2016-05-17 14:19:38 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
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
17package org.onosproject.yangutils.parser.impl.parserutils;
18
19import java.util.ArrayList;
20import java.util.List;
21
22import org.onosproject.yangutils.datamodel.CollisionDetector;
23import org.onosproject.yangutils.datamodel.YangModule;
24import org.onosproject.yangutils.datamodel.YangNode;
25import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
26import org.onosproject.yangutils.datamodel.YangSubModule;
27import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
28import org.onosproject.yangutils.parser.Parsable;
29import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
30import org.onosproject.yangutils.parser.exceptions.ParserException;
31import org.onosproject.yangutils.parser.impl.TreeWalkListener;
32
33import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getCapitalCase;
34import static org.onosproject.yangutils.utils.YangConstructType.AUGMENT_DATA;
35
36/**
37 * Represents a utility which provides listener utilities augment node.
38 */
39public final class AugmentListenerUtil {
40
41 /**
42 * Prefix to be added to generated java file for augment node.
43 */
44 private static final String AUGMENTED = "Augmented";
45
46 /**
47 * The number of time augment has updated the same target node in same module/submodule.
48 */
49 private static int occurrenceCount = 1;
50
51 /**
52 * List of names for augment's generated java file.
53 */
54 private static List<String> augmentJavaFileNameList = new ArrayList<>();
55
56 private static final int ONE = 1;
57 private static final int TWO = 2;
58 private static final int ZERO = 0;
59
60 /**
61 * Creates an instance of augment java file name generator utility.
62 */
63 private AugmentListenerUtil() {
64 }
65
66 /**
67 * Sets the augment java file name list.
68 *
69 * @param nameList name list
70 */
71 private static void setAugmentJavaFileNameList(List<String> nameList) {
72 augmentJavaFileNameList = nameList;
73 }
74
75 /**
76 * Returns augment java file name list.
77 *
78 * @return augment java file name list
79 */
80 public static List<String> getAugmentJavaFileNameList() {
81 return augmentJavaFileNameList;
82 }
83
84 /**
85 * Sets occurrence count.
86 *
87 * @param occurrence occurrence count
88 */
89 private static void setOccurrenceCount(int occurrence) {
90 occurrenceCount = occurrence;
91 }
92
93 /**
94 * Returns occurrence count.
95 *
96 * @return occurrence count
97 */
98 private static int getOccurrenceCount() {
99 return occurrenceCount;
100 }
101
102 /**
103 * Generates name for augment node also detects collision for java file generation of augment node when
104 * augment is updating the same target node in same parent multiple times.
105 *
106 * @param curData parsable data
107 * @param targetNodes list of target nodes
108 * @param listener tree walk listener
109 * @return name for augment node
110 */
111 public static String generateNameForAugmentNode(Parsable curData, List<YangNodeIdentifier> targetNodes,
112 TreeWalkListener listener) {
113
114 String curPrefix = getParentsPrefix((YangNode) curData);
115 YangNodeIdentifier nodeId = targetNodes.get(targetNodes.size() - 1);
116 boolean isPrefix = isPrefixPresent(nodeId, curPrefix);
117 String generateName = createValidNameForAugment(nodeId, isPrefix);
118
119 if (listener.getParsedDataStack().peek() instanceof CollisionDetector) {
120 try {
121 ((CollisionDetector) listener.getParsedDataStack().peek()).detectCollidingChild(generateName,
122 AUGMENT_DATA);
123 } catch (DataModelException e) {
124 return updateNameWhenHasMultipleOuccrrence(nodeId, isPrefix);
125 }
126 }
127
128 clearOccurrenceCount();
129 return generateName;
130 }
131
132 /**
133 * Creates a name identifier for augment.
134 *
135 * @param nodeId node identifier
136 * @param isPrefix if prefix is present or it is not equals to parent's prefix
137 * @return valid name for augment
138 */
139 public static String createValidNameForAugment(YangNodeIdentifier nodeId, boolean isPrefix) {
140 getAugmentJavaFileNameList().add(createName(nodeId, isPrefix));
141 setAugmentJavaFileNameList(getAugmentJavaFileNameList());
142 return getAugmentJavaFileNameList().get(getAugmentJavaFileNameList().size() - 1);
143 }
144
145 /**
146 * Creates name for the current augment file.
147 *
148 * @param nodeId node identifier
149 * @param isPrefix if prefix is present or it is not equals to parent's prefix
150 */
151 private static String createName(YangNodeIdentifier nodeId, boolean isPrefix) {
152 if (isPrefix) {
153 return AUGMENTED + getCapitalCase(nodeId.getPrefix()) + getCapitalCase(nodeId.getName());
154 } else {
155 return AUGMENTED + getCapitalCase(nodeId.getName());
156 }
157 }
158
159 /**
160 * Updates occurrence count of augment.
161 */
162 private static void updateOccurenceCount() {
163 int count = getOccurrenceCount();
164 count++;
165 setOccurrenceCount(count);
166 }
167
168 /**
169 * Updates the list of name when augment has occurred multiple times to update the same target node
170 * and returns a valid name for augment node's generated java file.
171 *
172 * @param nodeId YANG node identifier
173 * @param isPrefix true if a prefix is present and it is not equals to parents prefix
174 * @return valid name for augment node
175 */
176 public static String updateNameWhenHasMultipleOuccrrence(YangNodeIdentifier nodeId, boolean isPrefix) {
177 String name = "";
178 updateOccurenceCount();
179
180 if (getOccurrenceCount() == TWO) {
181 String previousAugmentsName = getAugmentJavaFileNameList().get(getAugmentJavaFileNameList().size() - ONE);
182 getAugmentJavaFileNameList().remove(ZERO);
183 getAugmentJavaFileNameList().add(previousAugmentsName + ONE);
184 //TODO: update when already contains the name.
185 name = createName(nodeId, isPrefix) + TWO;
186 } else {
187 name = createName(nodeId, isPrefix) + getOccurrenceCount();
188 }
189 getAugmentJavaFileNameList().add(name);
190 return name;
191 }
192
193 /**
194 * Resets occurrence count to one.
195 */
196 public static void clearOccurrenceCount() {
197 setOccurrenceCount(ONE);
198 }
199
200 /**
201 * Returns true if a prefix is present and it is not equals to parents prefix.
202 *
203 * @param nodeId YANG node identifier
204 * @param parentsPrefix parent's prefix
205 * @return true if a prefix is present and it is not equals to parents prefix
206 */
207 private static boolean isPrefixPresent(YangNodeIdentifier nodeId, String parentsPrefix) {
208 return nodeId.getPrefix() != null && nodeId.getPrefix() != parentsPrefix;
209 }
210
211 /**
212 * Validates whether current node in target path is valid or not.
213 *
214 * @param curNode current YANG node
215 * @param targetNodes list of target nodes
216 * @param ctx augment statement context
217 */
218 public static void validateNodeInTargetPath(YangNode curNode, List<YangNodeIdentifier> targetNodes,
219 GeneratedYangParser.AugmentStatementContext ctx) {
220
221 curNode = curNode.getChild();
222 YangNode tempNode = validateCurrentTargetNode(targetNodes, curNode);
223 if (tempNode != null) {
224 switch (tempNode.getNodeType()) {
225 case CONTAINER_NODE:
226 break;
227 case LIST_NODE:
228 break;
229 case CHOICE_NODE:
230 break;
231 case CASE_NODE:
232 break;
233 case INPUT_NODE:
234 break;
235 case OUTPUT_NODE:
236 break;
237 case NOTIFICATION_NODE:
238 break;
239 default:
240 throw parserException(ctx);
241 }
242 } else {
243 throw parserException(ctx);
244 }
245 }
246
247 /**
248 * Validates whether nodes in target node list are valid or not.
249 *
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530250 * @param targetNodes target node
Bharat saraswalab4c6ba2016-05-17 14:19:38 +0530251 * @param curNode YANG node
252 * @return true or false
253 */
254 private static YangNode validateCurrentTargetNode(List<YangNodeIdentifier> targetNodes, YangNode curNode) {
255 YangNode tempNode = null;
256 while (curNode != null) {
257 tempNode = curNode;
258 for (int i = 1; i < targetNodes.size(); i++) {
259 if (curNode.getName().equals(targetNodes.get(i).getName())) {
260 if (curNode.getChild() != null && targetNodes.size() - 1 != i) {
261 curNode = curNode.getChild();
262 } else if (curNode.getChild() != null && targetNodes.size() - 1 == i) {
263 return curNode;
264 } else if (curNode.getChild() == null && targetNodes.size() - 1 == i) {
265 return curNode;
266 } else {
267 break;
268 }
269 } else {
270 curNode = tempNode;
271 break;
272 }
273 }
274 curNode = curNode.getNextSibling();
275 }
276 return null;
277 }
278
279 /**
280 * Builds parser exception.
281 *
282 * @param ctx augment statement context
283 * @return parser exception
284 */
285 public static ParserException parserException(GeneratedYangParser.AugmentStatementContext ctx) {
286 int line = ctx.getStart().getLine();
287 int charPositionInLine = ctx.getStart().getCharPositionInLine();
288 ParserException exception = new ParserException("invalid target node path.");
289 exception.setLine(line);
290 exception.setCharPosition(charPositionInLine);
291 return exception;
292 }
293
294 /**
295 * Returns parent nodes prefix.
296 *
297 * @param curNode current YANG node
298 * @return parent nodes prefix
299 */
300 public static String getParentsPrefix(YangNode curNode) {
301 String curPrefix = null;
302 if (curNode instanceof YangModule) {
303 curPrefix = ((YangModule) curNode).getPrefix();
304 } else if (curNode instanceof YangSubModule) {
305 curPrefix = ((YangSubModule) curNode).getPrefix();
306 }
307 return curPrefix;
308 }
309}