blob: 7aae7679222ca73d5c5816d4d16e08077eac6d0a [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yangutils.parser.impl.parserutils;
import java.util.ArrayList;
import java.util.List;
import org.onosproject.yangutils.datamodel.CollisionDetector;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
import org.onosproject.yangutils.datamodel.YangSubModule;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getCapitalCase;
import static org.onosproject.yangutils.utils.YangConstructType.AUGMENT_DATA;
/**
* Represents a utility which provides listener utilities augment node.
*/
public final class AugmentListenerUtil {
/**
* Prefix to be added to generated java file for augment node.
*/
private static final String AUGMENTED = "Augmented";
/**
* The number of time augment has updated the same target node in same module/submodule.
*/
private static int occurrenceCount = 1;
/**
* List of names for augment's generated java file.
*/
private static List<String> augmentJavaFileNameList = new ArrayList<>();
private static final int ONE = 1;
private static final int TWO = 2;
private static final int ZERO = 0;
/**
* Creates an instance of augment java file name generator utility.
*/
private AugmentListenerUtil() {
}
/**
* Sets the augment java file name list.
*
* @param nameList name list
*/
private static void setAugmentJavaFileNameList(List<String> nameList) {
augmentJavaFileNameList = nameList;
}
/**
* Returns augment java file name list.
*
* @return augment java file name list
*/
public static List<String> getAugmentJavaFileNameList() {
return augmentJavaFileNameList;
}
/**
* Sets occurrence count.
*
* @param occurrence occurrence count
*/
private static void setOccurrenceCount(int occurrence) {
occurrenceCount = occurrence;
}
/**
* Returns occurrence count.
*
* @return occurrence count
*/
private static int getOccurrenceCount() {
return occurrenceCount;
}
/**
* Generates name for augment node also detects collision for java file generation of augment node when
* augment is updating the same target node in same parent multiple times.
*
* @param curData parsable data
* @param targetNodes list of target nodes
* @param listener tree walk listener
* @return name for augment node
*/
public static String generateNameForAugmentNode(Parsable curData, List<YangNodeIdentifier> targetNodes,
TreeWalkListener listener) {
String curPrefix = getParentsPrefix((YangNode) curData);
YangNodeIdentifier nodeId = targetNodes.get(targetNodes.size() - 1);
boolean isPrefix = isPrefixPresent(nodeId, curPrefix);
String generateName = createValidNameForAugment(nodeId, isPrefix);
if (listener.getParsedDataStack().peek() instanceof CollisionDetector) {
try {
((CollisionDetector) listener.getParsedDataStack().peek()).detectCollidingChild(generateName,
AUGMENT_DATA);
} catch (DataModelException e) {
return updateNameWhenHasMultipleOuccrrence(nodeId, isPrefix);
}
}
clearOccurrenceCount();
return generateName;
}
/**
* Creates a name identifier for augment.
*
* @param nodeId node identifier
* @param isPrefix if prefix is present or it is not equals to parent's prefix
* @return valid name for augment
*/
public static String createValidNameForAugment(YangNodeIdentifier nodeId, boolean isPrefix) {
getAugmentJavaFileNameList().add(createName(nodeId, isPrefix));
setAugmentJavaFileNameList(getAugmentJavaFileNameList());
return getAugmentJavaFileNameList().get(getAugmentJavaFileNameList().size() - 1);
}
/**
* Creates name for the current augment file.
*
* @param nodeId node identifier
* @param isPrefix if prefix is present or it is not equals to parent's prefix
*/
private static String createName(YangNodeIdentifier nodeId, boolean isPrefix) {
if (isPrefix) {
return AUGMENTED + getCapitalCase(nodeId.getPrefix()) + getCapitalCase(nodeId.getName());
} else {
return AUGMENTED + getCapitalCase(nodeId.getName());
}
}
/**
* Updates occurrence count of augment.
*/
private static void updateOccurenceCount() {
int count = getOccurrenceCount();
count++;
setOccurrenceCount(count);
}
/**
* Updates the list of name when augment has occurred multiple times to update the same target node
* and returns a valid name for augment node's generated java file.
*
* @param nodeId YANG node identifier
* @param isPrefix true if a prefix is present and it is not equals to parents prefix
* @return valid name for augment node
*/
public static String updateNameWhenHasMultipleOuccrrence(YangNodeIdentifier nodeId, boolean isPrefix) {
String name = "";
updateOccurenceCount();
if (getOccurrenceCount() == TWO) {
String previousAugmentsName = getAugmentJavaFileNameList().get(getAugmentJavaFileNameList().size() - ONE);
getAugmentJavaFileNameList().remove(ZERO);
getAugmentJavaFileNameList().add(previousAugmentsName + ONE);
//TODO: update when already contains the name.
name = createName(nodeId, isPrefix) + TWO;
} else {
name = createName(nodeId, isPrefix) + getOccurrenceCount();
}
getAugmentJavaFileNameList().add(name);
return name;
}
/**
* Resets occurrence count to one.
*/
public static void clearOccurrenceCount() {
setOccurrenceCount(ONE);
}
/**
* Returns true if a prefix is present and it is not equals to parents prefix.
*
* @param nodeId YANG node identifier
* @param parentsPrefix parent's prefix
* @return true if a prefix is present and it is not equals to parents prefix
*/
private static boolean isPrefixPresent(YangNodeIdentifier nodeId, String parentsPrefix) {
return nodeId.getPrefix() != null && nodeId.getPrefix() != parentsPrefix;
}
/**
* Validates whether current node in target path is valid or not.
*
* @param curNode current YANG node
* @param targetNodes list of target nodes
* @param ctx augment statement context
*/
public static void validateNodeInTargetPath(YangNode curNode, List<YangNodeIdentifier> targetNodes,
GeneratedYangParser.AugmentStatementContext ctx) {
curNode = curNode.getChild();
YangNode tempNode = validateCurrentTargetNode(targetNodes, curNode);
if (tempNode != null) {
switch (tempNode.getNodeType()) {
case CONTAINER_NODE:
break;
case LIST_NODE:
break;
case CHOICE_NODE:
break;
case CASE_NODE:
break;
case INPUT_NODE:
break;
case OUTPUT_NODE:
break;
case NOTIFICATION_NODE:
break;
default:
throw parserException(ctx);
}
} else {
throw parserException(ctx);
}
}
/**
* Validates whether nodes in target node list are valid or not.
*
* @param targetNodes target node
* @param curNode YANG node
* @return true or false
*/
private static YangNode validateCurrentTargetNode(List<YangNodeIdentifier> targetNodes, YangNode curNode) {
YangNode tempNode = null;
while (curNode != null) {
tempNode = curNode;
for (int i = 1; i < targetNodes.size(); i++) {
if (curNode.getName().equals(targetNodes.get(i).getName())) {
if (curNode.getChild() != null && targetNodes.size() - 1 != i) {
curNode = curNode.getChild();
} else if (curNode.getChild() != null && targetNodes.size() - 1 == i) {
return curNode;
} else if (curNode.getChild() == null && targetNodes.size() - 1 == i) {
return curNode;
} else {
break;
}
} else {
curNode = tempNode;
break;
}
}
curNode = curNode.getNextSibling();
}
return null;
}
/**
* Builds parser exception.
*
* @param ctx augment statement context
* @return parser exception
*/
public static ParserException parserException(GeneratedYangParser.AugmentStatementContext ctx) {
int line = ctx.getStart().getLine();
int charPositionInLine = ctx.getStart().getCharPositionInLine();
ParserException exception = new ParserException("invalid target node path.");
exception.setLine(line);
exception.setCharPosition(charPositionInLine);
return exception;
}
/**
* Returns parent nodes prefix.
*
* @param curNode current YANG node
* @return parent nodes prefix
*/
public static String getParentsPrefix(YangNode curNode) {
String curPrefix = null;
if (curNode instanceof YangModule) {
curPrefix = ((YangModule) curNode).getPrefix();
} else if (curNode instanceof YangSubModule) {
curPrefix = ((YangSubModule) curNode).getPrefix();
}
return curPrefix;
}
}