Vidyashree Rama
Committed by Gerrit Code Review

YANG sub module linking + unsupported yang construct + defect fix

Change-Id: I224c8c14ee2111f6844278cb540c48651544f59b
Showing 55 changed files with 1402 additions and 163 deletions
......@@ -57,6 +57,11 @@ public class YangBelongsTo implements Parsable {
private String belongsToModuleName;
/**
* Module node to which sub-module belongs to.
*/
private YangNode moduleNode;
/**
* Reference RFC 6020.
*
* The mandatory "prefix" substatement assigns a prefix for the module to
......@@ -110,6 +115,24 @@ public class YangBelongsTo implements Parsable {
}
/**
* Returns the module data model node.
*
* @return the module data model node
*/
public YangNode getModuleNode() {
return moduleNode;
}
/**
* Sets the module node.
*
* @param moduleNode module data model node
*/
public void setModuleNode(YangNode moduleNode) {
this.moduleNode = moduleNode;
}
/**
* Returns the type of the data as belongs-to.
*
* @return ParsedDataType returns BELONGS_TO_DATA
......
......@@ -135,6 +135,12 @@ public class YangChoice extends YangNode
private YangStatusType status;
/**
* Default value in string, needs to be converted to the target object,
* based on the type.
*/
private String defaultValueInString;
/**
* Create a choice node.
*/
public YangChoice() {
......@@ -276,6 +282,24 @@ public class YangChoice extends YangNode
}
/**
* Returns the default value.
*
* @return the default value
*/
public String getDefaultValueInString() {
return defaultValueInString;
}
/**
* Sets the default value.
*
* @param defaultValueInString the default value
*/
public void setDefaultValueInString(String defaultValueInString) {
this.defaultValueInString = defaultValueInString;
}
/**
* Returns the type of the data.
*
* @return choice data
......
......@@ -101,6 +101,12 @@ public class YangLeaf
private YangType<?> dataType;
/**
* Default value in string, needs to be converted to the target object,
* based on the type.
*/
private String defaultValueInString;
/**
* Creates a YANG leaf.
*/
public YangLeaf() {
......@@ -239,6 +245,24 @@ public class YangLeaf
}
/**
* Returns the default value.
*
* @return the default value
*/
public String getDefaultValueInString() {
return defaultValueInString;
}
/**
* Sets the default value.
*
* @param defaultValueInString the default value
*/
public void setDefaultValueInString(String defaultValueInString) {
this.defaultValueInString = defaultValueInString;
}
/**
* Returns the data type.
*
* @return the data type
......
......@@ -445,16 +445,10 @@ public class YangList extends YangNode
/* A list must have atleast one key leaf if config is true */
if (isConfig
&& (keys == null || leaves == null && leafLists == null)) {
&& (keys == null || leaves == null && leafLists == null && !isUsesPresentInList())) {
throw new DataModelException("A list must have atleast one key leaf if config is true;");
} else if (keys != null) {
if (leaves != null) {
validateLeafKey(leaves, keys);
}
if (leafLists != null) {
validateLeafListKey(leafLists, keys);
}
validateKey(leaves, leafLists, keys);
}
}
......@@ -528,31 +522,51 @@ public class YangList extends YangNode
* Validates key statement of list.
*
* @param leaves list of leaf attributes of list
* @param leafLists list of leaf-list attributes of list
* @param keys list of key attributes of list
* @throws DataModelException a violation of data model rules
*/
private void validateLeafKey(List<YangLeaf> leaves, List<String> keys) throws DataModelException {
private void validateKey(List<YangLeaf> leaves, List<YangLeafList> leafLists, List<String> keys) throws
DataModelException {
boolean leafFound = false;
List<YangLeaf> keyLeaves = new LinkedList<>();
List<YangLeafList> keyLeafLists = new LinkedList<>();
/*
* 1. Leaf identifier must refer to a child leaf of the list 2. A leaf
* that is part of the key must not be the built-in type "empty".
*/
for (String key : keys) {
for (YangLeaf leaf : leaves) {
if (key.equals(leaf.getName())) {
if (leaf.getDataType().getDataType() == YangDataTypes.EMPTY) {
throw new DataModelException(" A leaf that is part of the key must not be the built-in " +
"type \"empty\".");
if (leaves != null && !leaves.isEmpty()) {
for (YangLeaf leaf : leaves) {
if (key.equals(leaf.getName())) {
if (leaf.getDataType().getDataType() == YangDataTypes.EMPTY) {
throw new DataModelException(" A leaf that is part of the key must not be the built-in " +
"type \"empty\".");
}
leafFound = true;
keyLeaves.add(leaf);
break;
}
leafFound = true;
keyLeaves.add(leaf);
break;
}
}
if (!leafFound) {
throw new DataModelException("Leaf identifier must refer to a child leaf of the list");
if (leafLists != null && !leafLists.isEmpty()) {
for (YangLeafList leafList : leafLists) {
if (key.equals(leafList.getName())) {
if (leafList.getDataType().getDataType() == YangDataTypes.EMPTY) {
throw new DataModelException(" A leaf-list that is part of the key" +
" must not be the built-in type \"empty\".");
}
leafFound = true;
keyLeafLists.add(leafList);
break;
}
}
}
if (!leafFound && !isUsesPresentInList()) {
throw new DataModelException("An identifier, in key, must refer to a child leaf of the list");
}
leafFound = false;
}
......@@ -567,42 +581,8 @@ public class YangList extends YangNode
" \"config\" as the list itself.");
}
}
}
/**
* Validates key statement of list.
*
* @param leafLists list of leaf-list attributes of list
* @param keys list of key attributes of list
* @throws DataModelException a violation of data model rules
*/
private void validateLeafListKey(List<YangLeafList> leafLists, List<String> keys) throws DataModelException {
boolean leafFound = false;
List<YangLeafList> keyLeafLists = new LinkedList<>();
/*
* 1. Leaf identifier must refer to a child leaf of the list 2. A leaf
* that is part of the key must not be the built-in type "empty".
*/
for (String key : keys) {
for (YangLeafList leafList : leafLists) {
if (key.equals(leafList.getName())) {
if (leafList.getDataType().getDataType() == YangDataTypes.EMPTY) {
throw new DataModelException(" A leaf-list that is part of the key must not be the built-in " +
"type \"empty\".");
}
leafFound = true;
keyLeafLists.add(leafList);
break;
}
}
if (!leafFound) {
throw new DataModelException("Leaf-list identifier must refer to a child leaf of the list");
}
leafFound = false;
}
/*
/*
* All key leafs in a list MUST have the same value for their "config"
* as the list itself.
*/
......@@ -627,4 +607,16 @@ public class YangList extends YangNode
getName() + "\"");
}
}
private boolean isUsesPresentInList() {
YangNode node = this.getChild();
while (node != null) {
if (node instanceof YangUses) {
return true;
}
node = node.getNextSibling();
}
return false;
}
}
......
......@@ -19,6 +19,8 @@ package org.onosproject.yangutils.datamodel;
import java.util.LinkedList;
import java.util.List;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.utils.YangConstructType;
import org.onosproject.yangutils.utils.builtindatatype.YangBuiltInDataTypeInfo;
import static org.onosproject.yangutils.utils.builtindatatype.BuiltInTypeObjectFactory.getDataObjectFromString;
......@@ -55,7 +57,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
* @param <T> range type (data type)
*/
public class YangRangeRestriction<T extends YangBuiltInDataTypeInfo<T>>
implements YangDesc, YangReference, YangAppErrorInfo {
implements YangDesc, YangReference, YangAppErrorInfo, Parsable {
/**
* Ascending list of range interval restriction. If the restriction is a
......@@ -311,4 +313,19 @@ public class YangRangeRestriction<T extends YangBuiltInDataTypeInfo<T>>
public void setErrorAppTag(String errTag) {
errorAppTag = errTag;
}
@Override
public YangConstructType getYangConstructType() {
return YangConstructType.RANGE_DATA;
}
@Override
public void validateDataOnEntry() throws DataModelException {
//TODO: implement the method.
}
@Override
public void validateDataOnExit() throws DataModelException {
//TODO: implement the method.
}
}
......
......@@ -16,6 +16,9 @@
package org.onosproject.yangutils.datamodel;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.utils.YangConstructType;
import org.onosproject.yangutils.utils.builtindatatype.YangUint64;
/*-
......@@ -28,7 +31,7 @@ import org.onosproject.yangutils.utils.builtindatatype.YangUint64;
/**
* Represents the restriction for string data type.
*/
public class YangStringRestriction {
public class YangStringRestriction implements YangDesc, YangReference, YangAppErrorInfo, Parsable {
/*-
* Reference RFC 6020.
......@@ -77,6 +80,26 @@ public class YangStringRestriction {
private YangPatternRestriction patternRestriction;
/**
* Textual reference.
*/
private String reference;
/**
* Application's error message, to be used for data error.
*/
private String errorMessage;
/**
* Application's error tag, to be filled in data validation error response.
*/
private String errorAppTag;
/**
* Textual description.
*/
private String description;
/**
* Creates a YANG string restriction object.
*/
public YangStringRestriction() {
......@@ -129,4 +152,101 @@ public class YangStringRestriction {
}
getPatternRestriction().addPattern(newPattern);
}
/**
* Returns the textual reference of the string restriction.
*
* @return textual reference of the string restriction
*/
@Override
public String getReference() {
return reference;
}
/**
* Sets the textual reference of the string restriction.
*
* @param ref textual reference of the string restriction
*/
@Override
public void setReference(String ref) {
reference = ref;
}
/**
* Returns the description of the string restriction.
*
* @return description of the string restriction
*/
@Override
public String getDescription() {
return description;
}
/**
* Sets the description of the string restriction.
*
* @param desc description of the string restriction
*/
@Override
public void setDescription(String desc) {
description = desc;
}
/**
* Returns application's error message, to be used for data error.
*
* @return Application's error message, to be used for data error
*/
@Override
public String getGetErrorMessage() {
return errorMessage;
}
/**
* Sets Application's error message, to be used for data error.
*
* @param errMsg Application's error message, to be used for data error
*/
@Override
public void setErrorMessage(String errMsg) {
errorMessage = errMsg;
}
/**
* Returns application's error tag, to be used for data error.
*
* @return application's error tag, to be used for data error
*/
@Override
public String getGetErrorAppTag() {
return errorAppTag;
}
/**
* Sets application's error tag, to be used for data error.
*
* @param errTag application's error tag, to be used for data error.
*/
@Override
public void setErrorAppTag(String errTag) {
errorAppTag = errTag;
}
@Override
public YangConstructType getYangConstructType() {
return YangConstructType.PATTERN_DATA;
}
@Override
public void validateDataOnEntry() throws DataModelException {
//TODO: implement the method.
}
@Override
public void validateDataOnExit() throws DataModelException {
//TODO: implement the method.
}
}
......
......@@ -16,6 +16,7 @@
package org.onosproject.yangutils.datamodel.utils;
import java.util.Iterator;
import java.util.List;
import org.onosproject.yangutils.datamodel.CollisionDetector;
......@@ -29,6 +30,7 @@ import org.onosproject.yangutils.datamodel.YangResolutionInfo;
import org.onosproject.yangutils.datamodel.YangRpc;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.plugin.manager.YangFileInfo;
import org.onosproject.yangutils.utils.YangConstructType;
/**
......@@ -240,4 +242,26 @@ public final class DataModelUtils {
}
return false;
}
/**
* Returns module's data model node to which sub-module belongs to.
*
* @param yangFileInfo YANG file information
* @param belongsToModuleName name of the module to which sub-module belongs to
* @return module node to which sub-module belongs to
* @throws DataModelException when belongs to module node is not found
*/
public static YangNode findBelongsToModuleNode(List<YangFileInfo> yangFileInfo,
String belongsToModuleName) throws DataModelException {
Iterator<YangFileInfo> yangFileIterator = yangFileInfo.iterator();
while (yangFileIterator.hasNext()) {
YangFileInfo yangFile = yangFileIterator.next();
YangNode yangNode = yangFile.getRootNode();
if (yangNode.getName().equals(belongsToModuleName)) {
return yangNode;
}
}
throw new DataModelException("YANG file error : Module " + belongsToModuleName + " to which sub-module " +
"belongs to is not found.");
}
}
......
......@@ -26,6 +26,7 @@ import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNotification;
import org.onosproject.yangutils.datamodel.YangOutput;
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;
......@@ -133,12 +134,11 @@ public final class ContainerListener {
}
Parsable curData = listener.getParsedDataStack().peek();
if (curData instanceof YangModule || curData instanceof YangContainer
|| curData instanceof YangList || curData instanceof YangCase
|| curData instanceof YangNotification
if (curData instanceof YangModule || curData instanceof YangSubModule
|| curData instanceof YangContainer || curData instanceof YangList
|| curData instanceof YangCase || curData instanceof YangNotification
|| curData instanceof YangInput || curData instanceof YangOutput
|| curData instanceof YangAugment
|| curData instanceof YangGrouping) {
|| curData instanceof YangAugment || curData instanceof YangGrouping) {
YangNode curNode = (YangNode) curData;
try {
curNode.addChild(container);
......
......@@ -39,6 +39,8 @@ package org.onosproject.yangutils.parser.impl.listeners;
* defaultStatement : DEFAULT_KEYWORD string STMTEND;
*/
import org.onosproject.yangutils.datamodel.YangChoice;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
......@@ -83,6 +85,16 @@ public final class DefaultListener {
typeDef.setDefaultValueInString(ctx.string().getText());
break;
}
case LEAF_DATA: {
YangLeaf leaf = (YangLeaf) tmpNode;
leaf.setDefaultValueInString(ctx.string().getText());
break;
}
case CHOICE_DATA: {
YangChoice choice = (YangChoice) tmpNode;
choice.setDefaultValueInString(ctx.string().getText());
break;
}
default:
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
DEFAULT_DATA, ctx.string().getText(), ENTRY));
......
......@@ -146,7 +146,14 @@ public final class EnumListener {
boolean isValuePresent = false;
for (YangEnum curEnum : yangEnumeration.getEnumSet()) {
if (maxValue <= curEnum.getValue()) {
if (curEnum.getValue() == Integer.MAX_VALUE) {
ParserException parserException = new ParserException("YANG file error : "
+ "An enum value MUST be specified for enum substatements following the one"
+ "with the current highest value");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
} else if (maxValue <= curEnum.getValue()) {
maxValue = curEnum.getValue();
isValuePresent = true;
}
......@@ -161,8 +168,8 @@ public final class EnumListener {
} catch (DataModelException e) {
ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
DUPLICATE_ENTRY, ENUM_DATA, ctx.string().getText(), EXIT, e.getMessage()));
parserException.setLine(ctx.string().STRING(0).getSymbol().getLine());
parserException.setCharPosition(ctx.string().STRING(0).getSymbol().getCharPositionInLine());
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
break;
......@@ -173,8 +180,7 @@ public final class EnumListener {
}
} else {
throw new ParserException(
constructListenerErrorMessage(MISSING_CURRENT_HOLDER, ENUM_DATA, ctx.string().getText(),
EXIT));
constructListenerErrorMessage(MISSING_CURRENT_HOLDER, ENUM_DATA, ctx.string().getText(), EXIT));
}
}
}
......
......@@ -29,8 +29,10 @@ import org.onosproject.yangutils.utils.YangConstructType;
import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.utils.RestrictionResolver.processLengthRestriction;
......@@ -86,7 +88,7 @@ public final class LengthRestrictionListener {
Parsable tmpData = listener.getParsedDataStack().peek();
if (tmpData.getYangConstructType() == TYPE_DATA) {
YangType type = (YangType) tmpData;
setLengthRestriction(type, ctx);
setLengthRestriction(listener, type, ctx);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LENGTH_DATA,
ctx.length().getText(), ENTRY));
......@@ -96,10 +98,11 @@ public final class LengthRestrictionListener {
/**
* Sets the length restriction to type.
*
* @param listener listener's object
* @param type Yang type for which length restriction to be set
* @param ctx context object of the grammar rule
*/
private static void setLengthRestriction(YangType type,
private static void setLengthRestriction(TreeWalkListener listener, YangType type,
GeneratedYangParser.LengthStatementContext ctx) {
if (type.getDataType() == DERIVED) {
......@@ -132,5 +135,31 @@ public final class LengthRestrictionListener {
}
stringRestriction.setLengthRestriction(lengthRestriction);
listener.getParsedDataStack().push(lengthRestriction);
}
/**
* Performs validation and updates the data model tree.
* It is called when parser exits from grammar rule (length).
*
* @param listener listener's object
* @param ctx context object of the grammar rule
*/
public static void processLengthRestrictionExit(TreeWalkListener listener,
GeneratedYangParser.LengthStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, LENGTH_DATA, ctx.length().getText(), EXIT);
Parsable tmpData = listener.getParsedDataStack().peek();
if (tmpData instanceof YangRangeRestriction) {
listener.getParsedDataStack().pop();
} else if (tmpData instanceof YangType
&& ((YangType) tmpData).getDataType() == DERIVED) {
// TODO : need to handle in linker
} else {
throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, LENGTH_DATA,
ctx.length().getText(), EXIT));
}
}
}
......
......@@ -26,6 +26,7 @@ import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNotification;
import org.onosproject.yangutils.datamodel.YangOutput;
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;
......@@ -141,7 +142,8 @@ public final class ListListener {
if (curData instanceof YangModule || curData instanceof YangContainer
|| curData instanceof YangList || curData instanceof YangCase
|| curData instanceof YangNotification || curData instanceof YangInput
|| curData instanceof YangOutput || curData instanceof YangAugment || curData instanceof YangGrouping) {
|| curData instanceof YangOutput || curData instanceof YangAugment
|| curData instanceof YangGrouping || curData instanceof YangSubModule) {
curNode = (YangNode) curData;
try {
curNode.addChild(yangList);
......
......@@ -27,9 +27,12 @@ import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import org.onosproject.yangutils.utils.YangConstructType;
import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.utils.YangConstructType.PATTERN_DATA;
......@@ -84,7 +87,7 @@ public final class PatternRestrictionListener {
Parsable tmpData = listener.getParsedDataStack().peek();
if (tmpData.getYangConstructType() == TYPE_DATA) {
YangType type = (YangType) tmpData;
setPatternRestriction(type, ctx);
setPatternRestriction(listener, type, ctx);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, PATTERN_DATA,
ctx.string().getText(), ENTRY));
......@@ -94,10 +97,11 @@ public final class PatternRestrictionListener {
/**
* Sets the pattern restriction to type.
*
* @param listener listener's object
* @param type Yang type for which pattern restriction to be set
* @param ctx context object of the grammar rule
*/
private static void setPatternRestriction(YangType type,
private static void setPatternRestriction(TreeWalkListener listener, YangType type,
GeneratedYangParser.PatternStatementContext ctx) {
if (type.getDataType() != YangDataTypes.STRING && type.getDataType() != YangDataTypes.DERIVED) {
......@@ -121,6 +125,7 @@ public final class PatternRestrictionListener {
} else {
stringRestriction.addPattern(patternArgument);
}
listener.getParsedDataStack().push(stringRestriction);
} else {
YangPatternRestriction patternRestriction = (YangPatternRestriction) ((YangDerivedInfo<?>) type
.getDataTypeExtendedInfo()).getPatternRestriction();
......@@ -134,4 +139,29 @@ public final class PatternRestrictionListener {
}
}
}
/**
* Performs validation and updates the data model tree.
* It is called when parser exits from grammar rule (pattern).
*
* @param listener listener's object
* @param ctx context object of the grammar rule
*/
public static void processPatternRestrictionExit(TreeWalkListener listener,
GeneratedYangParser.PatternStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, PATTERN_DATA, ctx.string().getText(), EXIT);
Parsable tmpData = listener.getParsedDataStack().peek();
if (tmpData instanceof YangStringRestriction) {
listener.getParsedDataStack().pop();
} else if (tmpData instanceof YangType
&& ((YangType) tmpData).getDataType() == DERIVED) {
// TODO : need to handle in linker
} else {
throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, PATTERN_DATA,
ctx.string().getText(), EXIT));
}
}
}
......
......@@ -26,8 +26,10 @@ import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.utils.RestrictionResolver.isOfRangeRestrictedType;
......@@ -82,7 +84,7 @@ public final class RangeRestrictionListener {
Parsable tmpData = listener.getParsedDataStack().peek();
if (tmpData.getYangConstructType() == TYPE_DATA) {
YangType type = (YangType) tmpData;
setRangeRestriction(type, ctx);
setRangeRestriction(listener, type, ctx);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, RANGE_DATA,
ctx.range().getText(), ENTRY));
......@@ -92,10 +94,11 @@ public final class RangeRestrictionListener {
/**
* Sets the range restriction to type.
*
* @param listener listener's object
* @param type YANG type for which range restriction to be added
* @param ctx context object of the grammar rule
*/
private static void setRangeRestriction(YangType type,
private static void setRangeRestriction(TreeWalkListener listener, YangType type,
GeneratedYangParser.RangeStatementContext ctx) {
if (type.getDataType() == DERIVED) {
......@@ -122,5 +125,31 @@ public final class RangeRestrictionListener {
if (rangeRestriction != null) {
type.setDataTypeExtendedInfo(rangeRestriction);
}
listener.getParsedDataStack().push(rangeRestriction);
}
/**
* Performs validation and updates the data model tree.
* It is called when parser exits from grammar rule (range).
*
* @param listener listener's object
* @param ctx context object of the grammar rule
*/
public static void processRangeRestrictionExit(TreeWalkListener listener,
GeneratedYangParser.RangeStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, RANGE_DATA, ctx.range().getText(), EXIT);
Parsable tmpData = listener.getParsedDataStack().peek();
if (tmpData instanceof YangRangeRestriction) {
listener.getParsedDataStack().pop();
} else if (tmpData instanceof YangType
&& ((YangType) tmpData).getDataType() == DERIVED) {
// TODO : need to handle in linker
} else {
throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, RANGE_DATA,
ctx.range().getText(), EXIT));
}
}
}
\ No newline at end of file
......
......@@ -38,6 +38,7 @@ import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMes
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIntegerValue;
import static org.onosproject.yangutils.utils.YangConstructType.VALUE_DATA;
/**
......@@ -62,25 +63,28 @@ public final class ValueListener {
public static void processValueEntry(TreeWalkListener listener, GeneratedYangParser.ValueStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), ENTRY);
checkStackIsNotEmpty(listener, MISSING_HOLDER, VALUE_DATA, ctx.value().getText(), ENTRY);
// Validate value
int value = getValidIntegerValue(ctx.value().getText(), VALUE_DATA, ctx);
// Obtain the node of the stack.
Parsable tmpNode = listener.getParsedDataStack().peek();
switch (tmpNode.getYangConstructType()) {
case ENUM_DATA: {
YangEnum enumNode = (YangEnum) tmpNode;
if (!isEnumValueValid(listener, ctx)) {
if (!isEnumValueValid(listener, ctx, value)) {
ParserException parserException = new ParserException("Duplicate Value Entry");
parserException.setLine(ctx.INTEGER().getSymbol().getLine());
parserException.setCharPosition(ctx.INTEGER().getSymbol().getCharPositionInLine());
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
enumNode.setValue(Integer.valueOf(ctx.INTEGER().getText()));
enumNode.setValue(value);
break;
}
default:
throw new ParserException(
constructListenerErrorMessage(INVALID_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), ENTRY));
constructListenerErrorMessage(INVALID_HOLDER, VALUE_DATA, ctx.value().getText(), ENTRY));
}
}
......@@ -89,20 +93,22 @@ public final class ValueListener {
*
* @param listener Listener's object
* @param ctx context object of the grammar rule
* @param value enum value
* @return validation result
*/
private static boolean isEnumValueValid(TreeWalkListener listener, GeneratedYangParser.ValueStatementContext ctx) {
private static boolean isEnumValueValid(TreeWalkListener listener, GeneratedYangParser.ValueStatementContext ctx,
int value) {
Parsable enumNode = listener.getParsedDataStack().pop();
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), ENTRY);
checkStackIsNotEmpty(listener, MISSING_HOLDER, VALUE_DATA, ctx.value().getText(), ENTRY);
Parsable tmpNode = listener.getParsedDataStack().peek();
switch (tmpNode.getYangConstructType()) {
case ENUMERATION_DATA: {
YangEnumeration yangEnumeration = (YangEnumeration) tmpNode;
for (YangEnum curEnum : yangEnumeration.getEnumSet()) {
if (Integer.valueOf(ctx.INTEGER().getText()) == curEnum.getValue()) {
if (value == curEnum.getValue()) {
listener.getParsedDataStack().push(enumNode);
return false;
}
......@@ -113,7 +119,7 @@ public final class ValueListener {
default:
listener.getParsedDataStack().push(enumNode);
throw new ParserException(
constructListenerErrorMessage(INVALID_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), ENTRY));
constructListenerErrorMessage(INVALID_HOLDER, VALUE_DATA, ctx.value().getText(), ENTRY));
}
}
}
......
......@@ -29,6 +29,18 @@ import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.utils.YangConstructType;
import static org.onosproject.yangutils.utils.UtilConstants.ADD;
import static org.onosproject.yangutils.utils.UtilConstants.SPACE;
import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
import static org.onosproject.yangutils.utils.UtilConstants.COLON;
import static org.onosproject.yangutils.utils.UtilConstants.CARET;
import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
import static org.onosproject.yangutils.utils.UtilConstants.HYPHEN;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
import static org.onosproject.yangutils.utils.UtilConstants.FALSE;
import static org.onosproject.yangutils.utils.UtilConstants.YANG_FILE_ERROR;
/**
* Represents an utility for listener.
*/
......@@ -37,18 +49,10 @@ public final class ListenerUtil {
private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
private static final String DATE_PATTERN = "[0-9]{4}-([0-9]{2}|[0-9])-([0-9]{2}|[0-9])";
private static final String NON_NEGATIVE_INTEGER_PATTERN = "[0-9]+";
private static final String PLUS = "+";
private static final Pattern INTEGER_PATTERN = Pattern.compile("[-][0-9]+|[0-9]+");
private static final String ONE = "1";
private static final String TRUE_KEYWORD = "true";
private static final String FALSE_KEYWORD = "false";
private static final int IDENTIFIER_LENGTH = 64;
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String EMPTY_STRING = "";
private static final String HYPHEN = "-";
private static final String SLASH = "/";
private static final String SPACE = " ";
private static final String COLON = ":";
private static final String CARET = "^";
/**
* Creates a new listener util.
......@@ -65,7 +69,7 @@ public final class ListenerUtil {
public static String removeQuotesAndHandleConcat(String yangStringData) {
yangStringData = yangStringData.replace("\"", EMPTY_STRING);
String[] tmpData = yangStringData.split(Pattern.quote(PLUS));
String[] tmpData = yangStringData.split(Pattern.quote(ADD));
StringBuilder builder = new StringBuilder();
for (String yangString : tmpData) {
builder.append(yangString);
......@@ -171,6 +175,41 @@ public final class ListenerUtil {
}
/**
* Validates integer value.
*
* @param integerValue integer to be validated
* @param yangConstruct yang construct for creating error message
* @param ctx context object of the grammar rule
* @return valid integer value
*/
public static int getValidIntegerValue(String integerValue, YangConstructType yangConstruct,
ParserRuleContext ctx) {
String value = removeQuotesAndHandleConcat(integerValue);
if (!INTEGER_PATTERN.matcher(value).matches()) {
ParserException parserException = new ParserException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
"valid.");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
int valueInInteger;
try {
valueInInteger = Integer.parseInt(value);
} catch (NumberFormatException e) {
ParserException parserException = new ParserException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
"valid.");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
return valueInInteger;
}
/**
* Validates boolean value.
*
* @param booleanValue value to be validated
......@@ -182,9 +221,9 @@ public final class ListenerUtil {
ParserRuleContext ctx) {
String value = removeQuotesAndHandleConcat(booleanValue);
if (value.equals(TRUE_KEYWORD)) {
if (value.equals(TRUE)) {
return true;
} else if (value.equals(FALSE_KEYWORD)) {
} else if (value.equals(FALSE)) {
return false;
} else {
ParserException parserException = new ParserException("YANG file error : " +
......@@ -272,4 +311,21 @@ public final class ListenerUtil {
}
return targetNodes;
}
/**
* Throws parser exception for unsupported YANG constructs.
*
* @param yangConstructType yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @param errorInfo error information
*/
public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
ParserRuleContext ctx, String errorInfo) {
ParserException parserException = new ParserException(YANG_FILE_ERROR
+ QUOTES + YangConstructType.getYangConstructType(yangConstructType) + QUOTES
+ errorInfo);
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
}
\ No newline at end of file
......
/*
* 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.plugin.manager;
import org.onosproject.yangutils.datamodel.YangNode;
/**
* Represents YANG file information.
*/
public class YangFileInfo {
/**
* YANG file name.
*/
private String yangFileName;
/**
* Data model node after parsing YANG file.
*/
private YangNode rootNode;
/**
* Returns data model node for YANG file.
*
* @return data model node for YANG file
*/
public YangNode getRootNode() {
return rootNode;
}
/**
* Sets data model node for YANG file.
*
* @param rootNode of the Yang file
*/
public void setRootNode(YangNode rootNode) {
this.rootNode = rootNode;
}
/**
* Returns YANG file name.
*
* @return yangFileName YANG file name
*/
public String getYangFileName() {
return yangFileName;
}
/**
* Sets YANG file name.
*
* @param yangFileName YANG file name
*/
public void setYangFileName(String yangFileName) {
this.yangFileName = yangFileName;
}
}
......@@ -28,6 +28,8 @@ import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangSubModule;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.YangUtilsParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
......@@ -49,6 +51,7 @@ import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.addToSource;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.copyYangFilesToTarget;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getDirectory;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.findBelongsToModuleNode;
/**
* Represents ONOS YANG utility maven plugin.
......@@ -137,17 +140,22 @@ public class YangUtilManager extends AbstractMojo {
conflictResolver.setReplacementForPeriod(replacementForPeriod);
conflictResolver.setReplacementForHyphen(replacementForHyphen);
conflictResolver.setReplacementForUnderscore(replacementForUnderscore);
List<String> yangFiles = YangFileScanner.getYangFiles(searchDir);
List<YangFileInfo> yangFileInfo = YangFileScanner.getYangFiles(searchDir);
if (yangFileInfo == null || yangFileInfo.isEmpty()) {
// no files to translate
return;
}
YangPluginConfig yangPlugin = new YangPluginConfig();
yangPlugin.setCodeGenDir(codeGenDir);
yangPlugin.setConflictResolver(conflictResolver);
Iterator<String> yangFileIterator = yangFiles.iterator();
Iterator<YangFileInfo> yangFileIterator = yangFileInfo.iterator();
while (yangFileIterator.hasNext()) {
String yangFile = yangFileIterator.next();
YangFileInfo yangFile = yangFileIterator.next();
try {
YangNode yangNode = yangUtilsParser.getDataModel(yangFile);
YangNode yangNode = yangUtilsParser.getDataModel(yangFile.getYangFileName());
yangFile.setRootNode(yangNode);
setRootNode(yangNode);
generateJavaCode(yangNode, yangPlugin, yangFile);
} catch (ParserException e) {
String logInfo = "Error in file: " + e.getFileName();
if (e.getLineNumber() != 0) {
......@@ -163,8 +171,12 @@ public class YangUtilManager extends AbstractMojo {
}
}
resolveLinkingForSubModule(yangFileInfo);
translateToJava(yangFileInfo, yangPlugin);
addToSource(getDirectory(baseDir, genFilesDir) + DEFAULT_PKG, project, context);
copyYangFilesToTarget(yangFiles, getDirectory(baseDir, outputDirectory), project);
copyYangFilesToTarget(yangFileInfo, getDirectory(baseDir, outputDirectory), project);
} catch (Exception e) {
String fileName = "";
if (e instanceof TranslatorException) {
......@@ -220,4 +232,40 @@ public class YangUtilManager extends AbstractMojo {
this.rootNode = rootNode;
}
/**
* Translates to java code corresponding to the YANG schema.
*
* @param yangFileInfo YANG file information
* @param yangPlugin YANG plugin config
* @throws IOException when fails to generate java code file the current
* node
*/
public static void translateToJava(List<YangFileInfo> yangFileInfo, YangPluginConfig yangPlugin)
throws IOException {
Iterator<YangFileInfo> yangFileIterator = yangFileInfo.iterator();
while (yangFileIterator.hasNext()) {
YangFileInfo yangFile = yangFileIterator.next();
generateJavaCode(yangFile.getRootNode(), yangPlugin, yangFile.getYangFileName());
}
}
/**
* Resolves sub-module linking.
*
* @param yangFileInfo YANG file information
* @throws DataModelException when belongs-to module node is not found
*/
public static void resolveLinkingForSubModule(List<YangFileInfo> yangFileInfo) throws DataModelException {
Iterator<YangFileInfo> yangFileIterator = yangFileInfo.iterator();
while (yangFileIterator.hasNext()) {
YangFileInfo yangFile = yangFileIterator.next();
YangNode yangNode = yangFile.getRootNode();
if (yangNode instanceof YangSubModule) {
String belongsToModuleName = ((YangSubModule) yangNode).getBelongsTo()
.getBelongsToModuleName();
YangNode moduleNode = findBelongsToModuleNode(yangFileInfo, belongsToModuleName);
((YangSubModule) yangNode).getBelongsTo().setModuleNode(moduleNode);
}
}
}
}
......
......@@ -18,6 +18,7 @@ package org.onosproject.yangutils.translator.tojava.javamodel;
import java.io.IOException;
import org.onosproject.yangutils.datamodel.YangBelongsTo;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangSubModule;
import org.onosproject.yangutils.translator.exception.TranslatorException;
import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
......@@ -108,8 +109,7 @@ public class YangJavaSubModule
* @return the name space string of the module.
*/
private String getNameSpaceFromModule(YangBelongsTo belongsToInfo) {
// TODO Auto-generated method stub
return "";
return ((YangModule) belongsToInfo.getModuleNode()).getNameSpace().getUri();
}
/**
......
......@@ -257,6 +257,16 @@ public final class UtilConstants {
public static final String LISTENER_PKG = "org.onosproject.event";
/**
* Static attribute for colon.
*/
public static final String COLON = ":";
/**
* Static attribute for caret.
*/
public static final String CARET = "^";
/**
* Static attribute for input string.
*/
public static final String INPUT = "input";
......@@ -932,6 +942,22 @@ public final class UtilConstants {
public static final String YANG_UTILS_TODO = "//TODO: YANG utils generated code";
/**
* Static attribute for YANG file error.
*/
public static final String YANG_FILE_ERROR = "YANG file error : ";
/**
* Static attribute for unsupported error information.
*/
public static final String UNSUPPORTED_YANG_CONSTRUCT = " is not supported.";
/**
* Static attribute for currently unsupported error information.
*/
public static final String CURRENTLY_UNSUPPORTED = " is not supported in current version, please check wiki" +
" for YANG utils road map.";
/**
* Creates an instance of util constants.
*/
private UtilConstants() {
......
......@@ -287,7 +287,77 @@ public enum YangConstructType {
/**
* Identifies the YANG pattern element parsed data.
*/
PATTERN_DATA;
PATTERN_DATA,
/**
* Identifies the YANG extension element parsed data.
*/
EXTENSION_DATA,
/**
* Identifies the YANG identity element parsed data.
*/
IDENTITY_DATA,
/**
* Identifies the YANG base element parsed data.
*/
BASE_DATA,
/**
* Identifies the YANG feature element parsed data.
*/
FEATURE_DATA,
/**
* Identifies the YANG if-feature element parsed data.
*/
IF_FEATURE_DATA,
/**
* Identifies the YANG path element parsed data.
*/
PATH_DATA,
/**
* Identifies the YANG require-instance element parsed data.
*/
REQUIRE_INSTANCE_DATA,
/**
* Identifies the YANG ordered-by element parsed data.
*/
ORDERED_BY_DATA,
/**
* Identifies the YANG error-message element parsed data.
*/
ERROR_MESSAGE_DATA,
/**
* Identifies the YANG error-app-tag element parsed data.
*/
ERROR_APP_TAG_DATA,
/**
* Identifies the YANG unique element parsed data.
*/
UNIQUE_DATA,
/**
* Identifies the YANG refine element parsed data.
*/
REFINE_DATA,
/**
* Identifies the YANG deviation element parsed data.
*/
DEVIATION_DATA,
/**
* Identifies the YANG anyxml element parsed data.
*/
ANYXML_DATA;
/**
* Returns the YANG construct keyword corresponding to enum values.
......@@ -406,6 +476,34 @@ public enum YangConstructType {
return "length";
case PATTERN_DATA:
return "pattern";
case EXTENSION_DATA:
return "extension";
case IDENTITY_DATA:
return "identity";
case BASE_DATA:
return "base";
case FEATURE_DATA:
return "feature";
case IF_FEATURE_DATA:
return "if-feature";
case PATH_DATA:
return "path";
case REQUIRE_INSTANCE_DATA:
return "require-instance";
case ORDERED_BY_DATA:
return "ordered-by";
case ERROR_MESSAGE_DATA:
return "error-message";
case ERROR_APP_TAG_DATA:
return "error-app-tag";
case UNIQUE_DATA:
return "unique";
case REFINE_DATA:
return "refine";
case DEVIATION_DATA:
return "deviation";
case ANYXML_DATA:
return "anyxml";
default:
return "yang";
}
......
......@@ -21,6 +21,7 @@ import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import org.onosproject.yangutils.plugin.manager.YangFileInfo;
/**
* Represents utility for searching the files in a directory.
......@@ -51,17 +52,23 @@ public final class YangFileScanner {
}
/**
* Returns the list of YANG files.
* Returns the list of YANG file information.
*
* @param root specified directory
* @return list of YANG files
* @return list of YANG file information
* @throws NullPointerException when no files are there
* @throws IOException when files get deleted while performing the
* operations
*/
public static List<String> getYangFiles(String root) throws IOException {
return getFiles(root, YANG_FILE_EXTENTION);
public static List<YangFileInfo> getYangFiles(String root) throws IOException {
List<String> yangFiles = getFiles(root, YANG_FILE_EXTENTION);
List<YangFileInfo> fileInfo = new LinkedList<>();
for (String yangFile : yangFiles) {
YangFileInfo yangFileInfo = new YangFileInfo();
yangFileInfo.setYangFileName(yangFile);
fileInfo.add(yangFileInfo);
}
return fileInfo;
}
/**
......
......@@ -24,6 +24,7 @@ import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
......@@ -33,6 +34,7 @@ import org.apache.maven.project.MavenProject;
import org.slf4j.Logger;
import org.sonatype.plexus.build.incremental.BuildContext;
import org.onosproject.yangutils.plugin.manager.YangFileInfo;
import static org.onosproject.yangutils.utils.UtilConstants.COMMA;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
......@@ -245,15 +247,15 @@ public final class YangIoUtils {
/**
* Copies YANG files to the current project's output directory.
*
* @param yangFiles list of YANG files
* @param yangFileInfo list of YANG files
* @param outputDir project's output directory
* @param project maven project
* @throws IOException when fails to copy files to destination resource directory
*/
public static void copyYangFilesToTarget(List<String> yangFiles, String outputDir, MavenProject project)
public static void copyYangFilesToTarget(List<YangFileInfo> yangFileInfo, String outputDir, MavenProject project)
throws IOException {
List<File> files = getListOfFile(yangFiles);
List<File> files = getListOfFile(yangFileInfo);
String path = outputDir + TARGET_RESOURCE_PATH;
File targetDir = new File(path);
......@@ -272,13 +274,15 @@ public final class YangIoUtils {
/**
* Provides a list of files from list of strings.
*
* @param strings list of strings
* @param yangFileInfo list of yang file information
* @return list of files
*/
private static List<File> getListOfFile(List<String> strings) {
private static List<File> getListOfFile(List<YangFileInfo> yangFileInfo) {
List<File> files = new ArrayList<>();
for (String file : strings) {
files.add(new File(file));
Iterator<YangFileInfo> yangFileIterator = yangFileInfo.iterator();
while (yangFileIterator.hasNext()) {
YangFileInfo yangFile = yangFileIterator.next();
files.add(new File(yangFile.getYangFileName()));
}
return files;
}
......
......@@ -380,6 +380,7 @@ package org.onosproject.yangutils.parser.antlrgencode;
| leafListStatement
| listStatement
| choiceStatement
| anyxmlStatement
| usesStatement;
/**
......@@ -429,13 +430,26 @@ package org.onosproject.yangutils.parser.antlrgencode;
* instance-identifier-specification /
* bits-specification /
* union-specification
* TODO : decimal64-specification to be added
*
*/
typeBodyStatements : numericalRestrictions | stringRestrictions | enumSpecification
typeBodyStatements : numericalRestrictions | decimal64Specification | stringRestrictions | enumSpecification
| leafrefSpecification | identityrefSpecification | instanceIdentifierSpecification
| bitsSpecification | unionSpecification;
/**
* fraction-digits-stmt = fraction-digits-keyword sep
* fraction-digits-arg-str stmtend
*
* fraction-digits-arg-str = < a string that matches the rule
* fraction-digits-arg >
*
* fraction-digits-arg = ("1" ["0" / "1" / "2" / "3" / "4" /
* "5" / "6" / "7" / "8"])
* / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9"
*/
decimal64Specification : FRACTION_DIGITS_KEYWORD fraction STMTEND;
/**
* numerical-restrictions = range-stmt stmtsep
*/
numericalRestrictions : rangeStatement;
......@@ -746,7 +760,7 @@ package org.onosproject.yangutils.parser.antlrgencode;
/**
* value-stmt = value-keyword sep integer-value stmtend
*/
valueStatement : VALUE_KEYWORD ((MINUS INTEGER) | INTEGER) STMTEND;
valueStatement : VALUE_KEYWORD value STMTEND;
/**
* grouping-stmt = grouping-keyword sep identifier-arg-str optsep
......@@ -899,7 +913,7 @@ package org.onosproject.yangutils.parser.antlrgencode;
* list-stmt /
* anyxml-stmt
*/
shortCaseStatement : containerStatement | leafStatement | leafListStatement | listStatement;
shortCaseStatement : containerStatement | leafStatement | leafListStatement | listStatement | anyxmlStatement;
/**
* case-stmt = case-keyword sep identifier-arg-str optsep
......@@ -919,6 +933,25 @@ package org.onosproject.yangutils.parser.antlrgencode;
| descriptionStatement | referenceStatement | dataDefStatement)* RIGHT_CURLY_BRACE);
/**
* anyxml-stmt = anyxml-keyword sep identifier-arg-str optsep
* (";" /
* "{" stmtsep
* ;; these stmts can appear in any order
* [when-stmt stmtsep]
* *(if-feature-stmt stmtsep)
* *(must-stmt stmtsep)
* [config-stmt stmtsep]
* [mandatory-stmt stmtsep]
* [status-stmt stmtsep]
* [description-stmt stmtsep]
* [reference-stmt stmtsep]
* "}")
*/
anyxmlStatement : ANYXML_KEYWORD identifier (STMTEND | LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement
| mustStatement | configStatement | mandatoryStatement | statusStatement | descriptionStatement
| referenceStatement)* RIGHT_CURLY_BRACE);
/**
* uses-stmt = uses-keyword sep identifier-ref-arg-str optsep
* (";" /
* "{" stmtsep
......@@ -934,7 +967,7 @@ package org.onosproject.yangutils.parser.antlrgencode;
* TODO : 0..1 occurance to be checked in listener
*/
usesStatement : USES_KEYWORD string (STMTEND | LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement | statusStatement
| descriptionStatement | referenceStatement | refineStatement | usesAugmentStatement)* RIGHT_CURLY_BRACE);
| descriptionStatement | referenceStatement | refineStatement | augmentStatement)* RIGHT_CURLY_BRACE);
/**
* refine-stmt = refine-keyword sep refine-arg-str optsep
......@@ -951,7 +984,7 @@ package org.onosproject.yangutils.parser.antlrgencode;
*/
refineStatement : REFINE_KEYWORD refine (STMTEND | LEFT_CURLY_BRACE (refineContainerStatements
| refineLeafStatements | refineLeafListStatements | refineListStatements | refineChoiceStatements
| refineCaseStatements) RIGHT_CURLY_BRACE);
| refineCaseStatements | refineAnyxmlStatements) RIGHT_CURLY_BRACE);
/**
* refine-container-stmts =
......@@ -1024,22 +1057,15 @@ package org.onosproject.yangutils.parser.antlrgencode;
refineCaseStatements : (descriptionStatement | referenceStatement)? | (referenceStatement | descriptionStatement)?;
/**
* uses-augment-stmt = augment-keyword sep uses-augment-arg-str optsep
* "{" stmtsep
* ;; these stmts can appear in any order
* [when-stmt stmtsep]
* *(if-feature-stmt stmtsep)
* [status-stmt stmtsep]
* [description-stmt stmtsep]
* [reference-stmt stmtsep]
* 1*((data-def-stmt stmtsep) /
* (case-stmt stmtsep))
* "}"
* TODO : 0..1 occurance to be checked in listener
* refine-anyxml-stmts = ;; these stmts can appear in any order
* *(must-stmt stmtsep)
* [config-stmt stmtsep]
* [mandatory-stmt stmtsep]
* [description-stmt stmtsep]
* [reference-stmt stmtsep]
*/
usesAugmentStatement : AUGMENT_KEYWORD augment LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement
| statusStatement | descriptionStatement | referenceStatement | dataDefStatement
| caseStatement)* RIGHT_CURLY_BRACE;
refineAnyxmlStatements : (mustStatement | configStatement | mandatoryStatement | descriptionStatement
| referenceStatement)*;
/**
* augment-stmt = augment-keyword sep augment-arg-str optsep
......@@ -1251,6 +1277,10 @@ package org.onosproject.yangutils.parser.antlrgencode;
deviation : string;
value : string;
fraction : string;
yangConstruct : ANYXML_KEYWORD | ARGUMENT_KEYWORD | AUGMENT_KEYWORD | BASE_KEYWORD | BELONGS_TO_KEYWORD
| BIT_KEYWORD | CASE_KEYWORD | CHOICE_KEYWORD | CONFIG_KEYWORD | CONTACT_KEYWORD | CONTAINER_KEYWORD
| DEFAULT_KEYWORD | DESCRIPTION_KEYWORD | ENUM_KEYWORD ERROR_APP_TAG_KEYWORD | ERROR_MESSAGE_KEYWORD
......
/*
* 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;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.parser.exceptions.ParserException;
/**
* Test cases for testing tree walk listener functionality.
*/
public class TreeWalkListenerTest {
private final YangUtilsParserManager manager = new YangUtilsParserManager();
@Rule
public ExpectedException thrown = ExpectedException.none();
/**
* Checks whether exception is thrown for ordered statement.
*/
@Test
public void processOrderedByStatement() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("YANG file error : \"ordered-by\" is not supported in current version, please check wiki" +
" for YANG utils road map.");
manager.getDataModel("src/test/resources/OrderedByStatement.yang");
}
/**
* Checks whether exception is thrown for anyxml statement.
*/
@Test
public void processAnyXmlStatement() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("YANG file error : \"anyxml\" is not supported.");
manager.getDataModel("src/test/resources/AnyxmlStatement.yang");
}
}
......@@ -134,9 +134,9 @@ public class ConfigListenerTest {
@Test
public void processModuleSubStatementConfig() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("mismatched input 'config' expecting {'augment', 'choice', 'contact', 'container',"
+ " 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import', 'include', "
+ "'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference',"
thrown.expectMessage("mismatched input 'config' expecting {'anyxml', 'augment', 'choice', 'contact', "
+ "'container', 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import',"
+ " 'include', 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference',"
+ " 'revision', 'rpc', 'typedef', 'uses', '}'}");
YangNode node = manager.getDataModel("src/test/resources/ModuleSubStatementConfig.yang");
}
......
/*
* 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.listeners;
import java.io.IOException;
import java.util.ListIterator;
import org.junit.Test;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangChoice;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
/**
* Test cases for testing default listener functionality.
*/
public class DefaultListenerTest {
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks if default value is set correctly.
*/
@Test
public void processLeafSubStatementDefault() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/LeafSubStatementDefault.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("invalid-interval"));
assertThat(leafInfo.getDefaultValueInString(), is("\"1\""));
}
/**
* Checks if default value is set correctly.
*/
@Test
public void processChoiceSubStatementDefault() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ChoiceSubStatementDefault.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
YangContainer yangContainer = (YangContainer) yangNode.getChild();
assertThat(yangContainer.getName(), is("food"));
YangChoice yangChoice = (YangChoice) yangContainer.getChild();
assertThat(yangChoice.getName(), is("snack"));
assertThat(yangChoice.getDefaultValueInString(), is("\"hello\""));
}
}
......@@ -18,7 +18,10 @@ package org.onosproject.yangutils.parser.impl.listeners;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.datamodel.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangEnum;
import org.onosproject.yangutils.datamodel.YangEnumeration;
......@@ -38,6 +41,9 @@ import java.util.Set;
*/
public class EnumListenerTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
......@@ -84,7 +90,28 @@ public class EnumListenerTest {
*/
@Test(expected = ParserException.class)
public void processEnumWithDuplicateName() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/EnumWithDuplicateName.yang");
}
/**
* Checks enum boundary value.
*/
@Test
public void processEnumBoundaryValue() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("YANG file error : value value 21474836472147483647 is not valid.");
YangNode node = manager.getDataModel("src/test/resources/EnumBoundaryValue.yang");
}
/**
* Checks whether exception is thrown if value is not specified following max enum value.
*/
@Test
public void processEnumMaxNextValue() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("YANG file error : "
+ "An enum value MUST be specified for enum substatements following the one"
+ "with the current highest value");
YangNode node = manager.getDataModel("src/test/resources/EnumMaxNextValue.yang");
}
}
......
......@@ -203,12 +203,32 @@ public class KeyListenerTest {
}
/**
* Checks key values are set correctly.
*/
@Test
public void processKeyWithUsesInList() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/KeyWithUsesInList.yang");
assertThat((node instanceof YangModule), is(true));
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
// Check whether the list is child of module
YangList yangList = (YangList) yangNode.getChild().getNextSibling();
assertThat(yangList.getName(), is("valid"));
ListIterator<String> keyList = yangList.getKeyList().listIterator();
assertThat(keyList.next(), is("invalid-interval"));
}
/**
* Checks whether exception is thrown when key leaf identifier is not found in list.
*/
@Test
public void processInvalidLeafIdentifier() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("Leaf identifier must refer to a child leaf of the list");
thrown.expectMessage("An identifier, in key, must refer to a child leaf of the list");
YangNode node = manager.getDataModel("src/test/resources/InvalidLeafIdentifier.yang");
}
......@@ -218,7 +238,7 @@ public class KeyListenerTest {
@Test
public void processInvalidLeafListIdentifier() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("Leaf-list identifier must refer to a child leaf of the list");
thrown.expectMessage("An identifier, in key, must refer to a child leaf of the list");
YangNode node = manager.getDataModel("src/test/resources/InvalidLeafListIdentifier.yang");
}
......
......@@ -94,9 +94,9 @@ public class LeafListListenerTest {
@Test
public void processLeafListInvalidStatement() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("mismatched input 'leaflist' expecting {'augment', 'choice', 'contact', 'container',"
+ " 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import', 'include',"
+ " 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference',"
thrown.expectMessage("mismatched input 'leaflist' expecting {'anyxml', 'augment', 'choice', 'contact', "
+ "'container', 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import',"
+ " 'include', 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference',"
+ " 'revision', 'rpc', 'typedef', 'uses', '}'}");
YangNode node = manager.getDataModel("src/test/resources/LeafListInvalidStatement.yang");
}
......
......@@ -95,9 +95,9 @@ public class LeafListenerTest {
@Test
public void processLeafInvalidStatement() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("mismatched input 'leafs' expecting {'augment', 'choice', 'contact', 'container',"
+ " 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import', 'include',"
+ " 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference',"
thrown.expectMessage("mismatched input 'leafs' expecting {'anyxml', 'augment', 'choice', 'contact', "
+ "'container', 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import',"
+ " 'include', 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference',"
+ " 'revision', 'rpc', 'typedef', 'uses', '}'}");
YangNode node = manager.getDataModel("src/test/resources/LeafInvalidStatement.yang");
}
......
......@@ -232,4 +232,39 @@ public class LengthRestrictionListenerTest {
" 18446744073709551615.");
YangNode node = manager.getDataModel("src/test/resources/LengthWithInvalidInterval.yang");
}
/**
* Checks valid length substatements.
*/
@Test
public void processLengthSubStatements() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/LengthSubStatements.yang");
assertThat((node instanceof YangModule), is(true));
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("invalid-interval"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
YangStringRestriction stringRestriction = (YangStringRestriction) leafInfo
.getDataType().getDataTypeExtendedInfo();
YangRangeRestriction lengthRestriction = stringRestriction.getLengthRestriction();
assertThat(lengthRestriction.getDescription(), is("\"length description\""));
assertThat(lengthRestriction.getReference(), is("\"length reference\""));
ListIterator<YangRangeInterval> lengthListIterator = lengthRestriction.getAscendingRangeIntervals()
.listIterator();
YangRangeInterval rangeInterval = lengthListIterator.next();
assertThat(((YangUint64) rangeInterval.getStartValue()).getValue(), is(BigInteger.valueOf(0)));
assertThat(((YangUint64) rangeInterval.getEndValue()).getValue(), is(BigInteger.valueOf(100)));
}
}
......
......@@ -148,9 +148,9 @@ public class MandatoryListenerTest {
@Test
public void processModuleSubStatementMandatory() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("mismatched input 'mandatory' expecting {'augment', 'choice', 'contact', 'container',"
+ " 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import', 'include',"
+ " 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference',"
thrown.expectMessage("mismatched input 'mandatory' expecting {'anyxml', 'augment', 'choice', 'contact',"
+ " 'container', 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import',"
+ " 'include', 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference',"
+ " 'revision', 'rpc', 'typedef', 'uses', '}'}");
YangNode node = manager.getDataModel("src/test/resources/ModuleSubStatementMandatory.yang");
}
......
......@@ -166,4 +166,32 @@ public class PatternRestrictionListenerTest {
.getPatternList().listIterator();
assertThat(patternListIterator.next(), is("-[0-9]+|[0-9]+"));
}
/**
* Checks valid pattern substatement.
*/
@Test
public void processPatternSubStatements() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/PatternSubStatements.yang");
assertThat((node instanceof YangModule), is(true));
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("invalid-interval"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("string"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.STRING));
YangStringRestriction stringRestriction = (YangStringRestriction) leafInfo
.getDataType().getDataTypeExtendedInfo();
assertThat(stringRestriction.getDescription(), is("\"pattern description\""));
assertThat(stringRestriction.getReference(), is("\"pattern reference\""));
ListIterator<String> patternListIterator = stringRestriction.getPatternRestriction()
.getPatternList().listIterator();
assertThat(patternListIterator.next(), is("[a-zA-Z]"));
}
}
......
......@@ -174,4 +174,37 @@ public class RangeRestrictionListenerTest {
thrown.expectMessage("YANG file error : Input value \"a\" is not a valid int32.");
YangNode node = manager.getDataModel("src/test/resources/RangeWithInvalidIntegerPattern.yang");
}
/**
* Checks valid range statement with description.
*/
@Test
public void processRangeSubStatements() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/RangeSubStatements.yang");
assertThat((node instanceof YangModule), is(true));
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("invalid-interval"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("int32"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.INT32));
YangRangeRestriction rangeRestriction = (YangRangeRestriction) leafInfo
.getDataType().getDataTypeExtendedInfo();
assertThat(rangeRestriction.getDescription(), is("\"range description\""));
assertThat(rangeRestriction.getReference(), is("\"range reference\""));
ListIterator<YangRangeInterval> rangeListIterator = rangeRestriction.getAscendingRangeIntervals()
.listIterator();
YangRangeInterval rangeInterval = rangeListIterator.next();
assertThat(((YangInt32) rangeInterval.getStartValue()).getValue(), is(1));
assertThat(((YangInt32) rangeInterval.getEndValue()).getValue(), is(4));
assertThat(((YangInt32) rangeInterval.getEndValue()).getValue(), is(4));
}
}
......
......@@ -150,9 +150,9 @@ public class StatusListenerTest {
@Test
public void processModuleSubStatementStatus() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("mismatched input 'status' expecting {'augment', 'choice', 'contact', 'container', "
+ "'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import', 'include',"
+ " 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference', "
thrown.expectMessage("mismatched input 'status' expecting {'anyxml', 'augment', 'choice', 'contact', "
+ "'container', 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import',"
+ " 'include', 'leaf', 'leaf-list', 'list', 'notification', 'organization', 'reference', "
+ "'revision', 'rpc', 'typedef', 'uses', '}'}");
YangNode node = manager.getDataModel("src/test/resources/ModuleSubStatementStatus.yang");
}
......
......@@ -76,9 +76,9 @@ public class UnitsListenerTest {
@Test
public void processModuleSubStatementUnits() throws IOException, ParserException {
thrown.expect(ParserException.class);
thrown.expectMessage("mismatched input 'type' expecting {'augment', 'choice', 'contact', 'container', "
+ "'description', 'extension', 'deviation', 'feature', 'grouping', 'identity', 'import', "
+ "'include', 'leaf', 'leaf-list', 'list', 'notification', 'organization', "
thrown.expectMessage("mismatched input 'type' expecting {'anyxml', 'augment', 'choice', 'contact', "
+ "'container', 'description', 'extension', 'deviation', 'feature', 'grouping', 'identity',"
+ " 'import', 'include', 'leaf', 'leaf-list', 'list', 'notification', 'organization', "
+ "'reference', 'revision', 'rpc', 'typedef', 'uses', '}'}");
YangNode node = manager.getDataModel("src/test/resources/ModuleSubStatementUnits.yang");
}
......
......@@ -80,6 +80,84 @@ public class ValueListenerTest {
}
/**
* Checks explicitly configured negative value.
*/
@Test
public void processValueStatementWithNegativeValue() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ValueStatementWithNegativeValue.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("speed"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("enumeration"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.ENUMERATION));
assertThat(((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getName(),
is("speed_enum"));
Set<YangEnum> enumSet = ((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getEnumSet();
for (YangEnum tmp : enumSet) {
if (tmp.getNamedValue().equals("10m")) {
assertThat(tmp.getValue(), is(-2));
} else if (tmp.getNamedValue().equals("100m")) {
assertThat(tmp.getValue(), is(-1));
} else if (tmp.getNamedValue().equals("auto")) {
assertThat(tmp.getValue(), is(0));
}
}
}
/**
* Checks explicitly configured value with double quotes.
*/
@Test
public void processValueStatementWithQuotes() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ValueStatementWithQuotes.yang");
// Check whether the data model tree returned is of type module.
assertThat((node instanceof YangModule), is(true));
// Check whether the node type is set properly to module.
assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
// Check whether the module name is set correctly.
YangModule yangNode = (YangModule) node;
assertThat(yangNode.getName(), is("Test"));
ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getName(), is("speed"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("enumeration"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.ENUMERATION));
assertThat(((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getName(),
is("speed_enum"));
Set<YangEnum> enumSet = ((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getEnumSet();
for (YangEnum tmp : enumSet) {
if (tmp.getNamedValue().equals("10m")) {
assertThat(tmp.getValue(), is(10));
} else if (tmp.getNamedValue().equals("100m")) {
assertThat(tmp.getValue(), is(100));
} else if (tmp.getNamedValue().equals("auto")) {
assertThat(tmp.getValue(), is(1000));
}
}
}
/**
* Checks explicit value and auto generated value.
*/
@Test
......
......@@ -26,6 +26,7 @@ import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.onosproject.yangutils.plugin.manager.YangFileInfo;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
......@@ -135,7 +136,7 @@ public final class YangFileScannerTest {
String emptyYangDir = baseDir + separator + "scanner1";
File path = createDirectory(emptyYangDir);
List<String> emptyDirContents = getYangFiles(path.toString());
List<YangFileInfo> emptyDirContents = getYangFiles(path.toString());
List<String> expectedContents = new LinkedList<>();
assertThat(true, is(emptyDirContents.equals(expectedContents)));
}
......
module event {
namespace "http://example.com/event";
prefix "ev";
notification event {
leaf event-class {
type string;
}
anyxml reporting-entity;
leaf severity {
type string;
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container food {
choice snack {
case sports-arena {
leaf pretzel {
type string;
}
leaf beer {
type string;
}
}
case late-night {
leaf chocolate {
type string;
}
}
default "hello";
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf ifType {
type enumeration {
enum "unbounded";
enum ZERO;
enum two;
enum four;
enum seven {
value 21474836472147483647;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf ifType {
type enumeration {
enum "unbounded";
enum ZERO;
enum two;
enum four;
enum seven {
value 2147483647;
}
enum five;
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
grouping network {
leaf invalid-interval {
type "string";
units "seconds";
status current;
reference "RFC 6020";
}
}
list valid {
key "invalid-interval";
leaf invalid {
type "string";
units "seconds";
status current;
reference "RFC 6020";
}
uses "network";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf invalid-interval {
type "uint16";
units "seconds";
default "1";
description "Interval before a route is declared invalid";
config true;
mandatory true;
status current;
reference "RFC 6020";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf invalid-interval {
type string {
length "0..100" {
description "length description";
reference "length reference";
}
}
}
}
module rock {
namespace "http://example.net/rock";
prefix "rock";
leaf-list cipher {
type string;
ordered-by user;
description "A list of ciphers";
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf invalid-interval {
type string {
pattern "[a-zA-Z]" {
description "pattern description";
reference "pattern reference";
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf invalid-interval {
type int32 {
range "1..4 | 10..20" {
description "range description";
reference "range reference";
}
}
}
}
......@@ -10,7 +10,6 @@ module Test {
prefix "P";
}
augment "/if:interfaces/if:ifEntry" {
when "if:ifType='ds0'";
leaf ds0ChannelNumber {
type P:ChannelNumber;
}
......
......@@ -14,9 +14,7 @@ module rock {
type int32;
}
leaf if-name {
type leafref {
path "/interface/name";
}
type leafref;
}
leaf if-admin-status {
type P:admin-status;
......
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf speed {
type enumeration {
enum 10m {
value -2;
}
enum 100m {
value "-1";
}
enum auto {
value 0;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf speed {
type enumeration {
enum 10m {
value "10";
}
enum 100m {
value "100";
}
enum auto {
value "1000";
}
}
}
}