diff options
author | Miranda Tsing <qingshuting1@huawei.com> | 2023-09-01 11:38:15 +0800 |
---|---|---|
committer | Miranda Tsing <qingshuting1@huawei.com> | 2023-09-01 17:20:52 +0800 |
commit | 1e401fb559a1d7cdf9e9210123969ddb884f8e67 (patch) | |
tree | 10e887f667ebb7b22c28cdbcd078db54b31dc704 /yang-comparator | |
parent | 0ad6f5a18a6e5cc98f464cfcdb78130acb80d0e6 (diff) |
Add comparator implementations for yang kit
Issue-ID: MODELING-680
Change-Id: Ibf49703746f4895c6ba705c4286ea849e4786386
Signed-off-by: Miranda Tsing <qingshuting1@huawei.com>
Diffstat (limited to 'yang-comparator')
31 files changed, 2663 insertions, 0 deletions
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AbstractYangStatementComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AbstractYangStatementComparator.java new file mode 100644 index 0000000..5e3af0f --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AbstractYangStatementComparator.java @@ -0,0 +1,59 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.List; + +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + +public abstract class AbstractYangStatementComparator<T extends YangStatement> implements YangStatementComparator<T> { + /** + * constructor. + */ + public AbstractYangStatementComparator() { + } + + /** + * get compatibility rules. + * + * @return rules + */ + public CompatibilityRules getCompatibilityRules() { + return CompatibilityRules.getInstance(); + } + + /** + * get change information. + * + * @param left left statement + * @param right right statement + * @return list of change information. + */ + protected abstract List<CompatibilityRule.ChangeInfo> getChangeInfo(T left, T right); + + /** + * the default compatibility result. + * + * @param left left statement + * @param right right statement + * @param changeInfo change information + * @return compatibility result + */ + protected abstract CompatibilityInfo defaultCompatibility(T left, T right, + CompatibilityRule.ChangeInfo changeInfo); +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AugmentComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AugmentComparator.java new file mode 100644 index 0000000..44fd21b --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AugmentComparator.java @@ -0,0 +1,50 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.model.api.stmt.Augment; + +public class AugmentComparator extends SchemaNodeComparator<Augment> { + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + public List<YangCompareResult> compare(Augment left, Augment right) { + if (left != null) { + if (left.getEffectiveSchemaNodeChildren().size() == 0) { + left = null; + } + } + if (right != null) { + if (right.getEffectiveSchemaNodeChildren().size() == 0) { + right = null; + } + } + List<YangCompareResult> compareResults = new ArrayList<>(); + if (left == null && right == null) { + return compareResults; + } + return compareChildren(left, right); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/BaseComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/BaseComparator.java new file mode 100644 index 0000000..d362fdd --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/BaseComparator.java @@ -0,0 +1,53 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.Base; +import org.yangcentral.yangkit.model.api.stmt.Identity; +import org.yangcentral.yangkit.model.api.stmt.Type; + + +public class BaseComparator extends CommonYangStatementComparator<Base> { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Base left, Base right, + CompatibilityRule.ChangeInfo changeInfo) { + Base temp = left; + if (temp == null) { + temp = right; + } + if (temp.getParentStatement() instanceof Identity) { + if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "delete a base for identity,it's non-backward-compatible."); + } + } else if (temp.getParentStatement() instanceof Type) { + if (changeInfo == CompatibilityRule.ChangeInfo.ADDED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "add a new base for identity-ref, it's non-backward-compatible."); + } + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ChangeType.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ChangeType.java new file mode 100644 index 0000000..6f7f818 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ChangeType.java @@ -0,0 +1,42 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + + + +public enum ChangeType { + ADD("add"), + MODIFY("modify"), + DELETE("delete"); + private String description; + + /** + * + * @param description + */ + private ChangeType(String description) { + this.description = description; + } + + /** + * + * @return + */ + public String getName() { + return this.description; + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java new file mode 100644 index 0000000..8b03304 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java @@ -0,0 +1,495 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.base.Cardinality; +import org.yangcentral.yangkit.base.YangElement; +import org.yangcentral.yangkit.base.YangStatementDef; +import org.yangcentral.yangkit.model.api.stmt.IdentifierRef; +import org.yangcentral.yangkit.model.api.stmt.Referencable; +import org.yangcentral.yangkit.model.api.stmt.SchemaNode; +import org.yangcentral.yangkit.model.api.stmt.YangBuiltinStatement; +import org.yangcentral.yangkit.model.api.stmt.YangStatement; +import org.yangcentral.yangkit.model.api.stmt.YangUnknown; + + +public class CommonYangStatementComparator<T extends YangStatement> extends AbstractYangStatementComparator<T> { + public static final int OPTION_ONLY_META = 1; + public static final int OPTION_ONLY_SCHEMA = 2; + public static final int OPTION_ALL = 3; + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(T left, T right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + if (left == null) { + changeInfos.add(CompatibilityRule.ChangeInfo.ADDED); + return changeInfos; + } + + if (right == null) { + changeInfos.add(CompatibilityRule.ChangeInfo.DELETED); + return changeInfos; + } + if (!yangStatementIsEqual(left, right)) { + changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED); + } + + int leftIndex = getIndex(left); + int rightIndex = getIndex(right); + if (leftIndex != rightIndex) { + changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED); + } + return changeInfos; + } + + /** + * + * @param stmt + * @return + */ + private int getIndex(T stmt) { + YangStatement parentStmt = stmt.getParentStatement(); + if (null == parentStmt) { + return -1; + } + int index = -1; + for (int i = 0; i < parentStmt.getSubElements().size(); i++) { + YangElement subElement = parentStmt.getSubElements().get(i); + if (subElement instanceof YangStatement) { + index++; + if (subElement == stmt) { + return index; + } + } + } + return index; + } + + /** + * + * @param changeInfo + * @return + */ + protected ChangeType getChangeType(CompatibilityRule.ChangeInfo changeInfo) { + switch (changeInfo) { + case ADDED: + case MANDATORY_ADDED: { + return ChangeType.ADD; + } + case DELETED: { + return ChangeType.DELETE; + } + default: { + return ChangeType.MODIFY; + } + } + } + + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(T left, T right, CompatibilityRule.ChangeInfo changeInfo) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.BC, null); + } + + /** + * get statement string representation. + * + * @param stmt statement + * @return string + */ + public static String getStatement(YangStatement stmt) { + if (stmt == null) { + return null; + } + String statement = null; + if (stmt instanceof YangBuiltinStatement) { + statement = stmt.getYangKeyword().getLocalName(); + } else { + YangUnknown unknown = (YangUnknown) stmt; + if (unknown.getExtension() == null) { + return unknown.getKeyword(); + } + String moduleName = unknown.getExtension().getContext().getCurModule().getMainModule().getArgStr(); + String extensionName = unknown.getExtension().getArgStr(); + statement = moduleName + ":" + extensionName; + } + return statement; + } + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + protected List<YangCompareResult> compareChildren(T left, T right) { + List<YangCompareResult> compareResults = + compareStatements(left == null ? new ArrayList<>() : left.getEffectiveSubStatements(), + right == null ? new ArrayList<>() : right.getEffectiveSubStatements(), OPTION_ONLY_META); + return compareResults; + } + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + public List<YangCompareResult> compare(T left, T right) { + List<YangCompareResult> compareResults = new ArrayList<>(); + List<CompatibilityRule.ChangeInfo> changeInfos = getChangeInfo(left, right); + if (!changeInfos.isEmpty()) { + YangStatement effectiveStmt = left == null ? right : left; + String statement = getStatement(effectiveStmt); + String parentStmt = getStatement(effectiveStmt.getParentStatement()); + for (CompatibilityRule.ChangeInfo changeInfo : changeInfos) { + if (changeInfo == CompatibilityRule.ChangeInfo.IGNORE) { + continue; + } + CompatibilityRule compatibilityRule = null; + if (null != getCompatibilityRules()) { + compatibilityRule = getCompatibilityRules().searchRule(statement, parentStmt, changeInfo); + } + if (compatibilityRule == null) { + //ignore sequence change + if (changeInfo != CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED) { + YangStatementCompareResult statementCompareResult = + new YangStatementCompareResult(getChangeType(changeInfo), left, right); + statementCompareResult.setCompatibilityInfo(defaultCompatibility(left, right, changeInfo)); + compareResults.add(statementCompareResult); + } + + } else { + YangStatementCompareResult statementCompareResult = + new YangStatementCompareResult(getChangeType(changeInfo), left, right); + statementCompareResult.setCompatibilityInfo( + new CompatibilityInfo(compatibilityRule.getCompatibility(), + compatibilityRule.getDescription())); + compareResults.add(statementCompareResult); + } + + } + } + + //sub statements + if (left != null && right != null) { + compareResults.addAll(compareChildren(left, right)); + } + return compareResults; + } + + /** + * calculate the similarity. + * + * @param src source statement + * @param candidate candidate statement + * @return similarity + */ + public static int calSimilarity(YangStatement src, YangStatement candidate) { + if (!src.getYangKeyword().equals(candidate.getYangKeyword())) { + return 0; + } + int similarity = 1; + + if (!src.equals(candidate)) { + return similarity; + } + similarity++; + List<YangStatement> srcSubStatements = src.getEffectiveSubStatements(); + List<YangStatement> candidateSubStatements = candidate.getEffectiveSubStatements(); + if (srcSubStatements.size() != candidateSubStatements.size()) { + return similarity; + } + similarity++; + List<YangStatement> matched = new ArrayList<>(); + for (YangStatement srcSubStatement : srcSubStatements) { + int maxSubSimilarity = 0; + YangStatement maxsimliaritySubStatement = null; + for (YangStatement candidateSubStatment : candidateSubStatements) { + if (contains(matched, candidateSubStatment)) { + continue; + } + int subSimilarity = calSimilarity(srcSubStatement, candidateSubStatment); + if (subSimilarity > maxSubSimilarity) { + maxSubSimilarity = subSimilarity; + maxsimliaritySubStatement = candidateSubStatment; + } + } + similarity += maxSubSimilarity; + matched.add(maxsimliaritySubStatement); + } + return similarity; + + } + + /** + * whether list contains an object. + * + * @param list a list + * @param obj object + * @return true or false + */ + public static boolean contains(List list, Object obj) { + if (list == null) { + return false; + } + for (Object src : list) { + if (src == obj) { + return true; + } + } + return false; + } + + /** + * search statement from target except matched statements. + * + * @param statement statement + * @param target target statements + * @param matched matched statements + * @return the searched statement + */ + public static YangStatement searchStatement(YangStatement statement, List<YangStatement> target, + List<YangStatement> matched) { + if (null == target || target.size() == 0) { + return null; + } + List<YangStatement> matchedTargetStmts = new ArrayList<>(); + for (YangStatement rightSubStatement : target) { + if (contains(matched, rightSubStatement)) { + continue; + } + if (yangStatementIsEqual(statement, rightSubStatement)) { + matchedTargetStmts.add(rightSubStatement); + continue; + } + } + if (matchedTargetStmts.size() == 1) { + return matchedTargetStmts.get(0); + } else if (matchedTargetStmts.size() > 1) { + int maxSimilarity = 0; + YangStatement maxSimilarStatement = null; + for (YangStatement matchedTargetStmt : matchedTargetStmts) { + int similarity = calSimilarity(statement, matchedTargetStmt); + if (similarity <= 1) { + continue; + } + if (similarity > maxSimilarity) { + maxSimilarity = similarity; + maxSimilarStatement = matchedTargetStmt; + } + } + if (maxSimilarStatement != null) { + return maxSimilarStatement; + } + } + + if (statement.getParentStatement() == null) { + return null; + } + + YangStatementDef statementDef = statement.getContext().getYangSpecification() + .getStatementDef(statement.getParentStatement().getYangKeyword()); + if (statementDef == null) { + if (statement.getParentStatement() instanceof YangUnknown) { + //unknown will be treated as cardinality with non-unbounded + for (YangStatement rightSubStatement : target) { + if (contains(matched, rightSubStatement)) { + continue; + } + return rightSubStatement; + } + return null; + } else { + return null; + } + } + + Cardinality cardinality = statementDef.getSubStatementCardinality(statement.getYangKeyword()); + if (cardinality == null) { + if (statement instanceof YangUnknown) { + //unknown will be treated as cardinality with non-unbounded + for (YangStatement rightSubStatement : target) { + if (contains(matched, rightSubStatement)) { + continue; + } + return rightSubStatement; + } + } + return null; + } + if (cardinality.isUnbounded()) { + return null; + } + + for (YangStatement rightSubStatement : target) { + if (contains(matched, rightSubStatement)) { + continue; + } + return rightSubStatement; + } + return null; + } + + /** + * whether the left statement is equal with right statement. + * + * @param left left statement + * @param right right statement + * @return true or false + */ + public static boolean yangStatementIsEqual(YangStatement left, YangStatement right) { + if ((left instanceof SchemaNode) && (right instanceof SchemaNode)) { + SchemaNode leftSchemaNode = (SchemaNode) left; + SchemaNode rightSchemaNode = (SchemaNode) right; + if (!left.getContext().getNamespace().equals(right.getContext().getNamespace())) { + return false; + } + if (!yangStatementIsEqual((YangStatement) leftSchemaNode.getClosestAncestorNode(), + (YangStatement) rightSchemaNode.getClosestAncestorNode())) { + return false; + } + } + if ((left instanceof IdentifierRef) && (right instanceof IdentifierRef)) { + if (!left.getYangKeyword().equals(right.getYangKeyword())) { + return false; + } + YangStatement leftRefStatement = ((IdentifierRef) left).getReferenceStatement(); + YangStatement rightRefStatement = ((IdentifierRef) right).getReferenceStatement(); + if (leftRefStatement != null && leftRefStatement.equals(rightRefStatement)) { + return true; + } else if (leftRefStatement == null && rightRefStatement == null) { + if (left.getArgStr().equals(right.getArgStr())) { + return true; + } else { + return false; + } + } else { + return false; + } + } + return left.equals(right); + } + + /** + * compare the two list of statements. + * + * @param leftElements the list of left statements + * @param rightElements the list of right statements + * @param option OPTION_ONLY_META =1/OPTION_ONLY_SCHEMA=2/OPTION_ALL=3 + * @return compare result + */ + public static List<YangCompareResult> compareStatements(List<? extends YangStatement> leftElements, + List<? extends YangStatement> rightElements, int option) { + List<YangCompareResult> compareResults = new ArrayList<>(); + List<YangStatement> foundStatements = new ArrayList<>(); + + if (leftElements.size() > 0) { + for (YangStatement subElement : leftElements) { + YangStatement leftSubStatement = subElement; + if (option == OPTION_ONLY_META) { + if ((leftSubStatement instanceof SchemaNode) + || (leftSubStatement instanceof Referencable)) { + continue; + } + } else if (option == OPTION_ONLY_SCHEMA) { + if (!(leftSubStatement instanceof SchemaNode)) { + continue; + } + } + if (leftSubStatement instanceof SchemaNode) { + SchemaNode leftSchemaNode = (SchemaNode) leftSubStatement; + if (!leftSchemaNode.isActive()) { + continue; + } + } + + List<YangStatement> rightSubStatements = new ArrayList<>(); + for (YangStatement rightElement : rightElements) { + if (leftSubStatement.getYangKeyword().equals(rightElement.getYangKeyword())) { + rightSubStatements.add(rightElement); + } + } + if (rightSubStatements.size() == 0) { + //no right statement, so change type is delete + YangStatementComparator comparator = + YangComparatorRegister.getInstance().getComparator(getStatement(leftSubStatement)); + compareResults.addAll(comparator.compare(leftSubStatement, null)); + continue; + } + YangStatement matchedRightSubStatement = + searchStatement(leftSubStatement, rightSubStatements, foundStatements); + if (null == matchedRightSubStatement) { + YangStatementComparator comparator = + YangComparatorRegister.getInstance().getComparator(getStatement(leftSubStatement)); + compareResults.addAll(comparator.compare(leftSubStatement, null)); + } else { + foundStatements.add(matchedRightSubStatement); + YangStatementComparator comparator = YangComparatorRegister.getInstance().getComparator( + getStatement(leftSubStatement == null ? matchedRightSubStatement : leftSubStatement)); + compareResults.addAll(comparator.compare(leftSubStatement, matchedRightSubStatement)); + } + } + } + if (rightElements.size() > 0) { + for (YangStatement subElement : rightElements) { + if (option == OPTION_ONLY_META) { + if ((subElement instanceof SchemaNode) + || (subElement instanceof Referencable)) { + continue; + } + } else if (option == OPTION_ONLY_SCHEMA) { + if (!(subElement instanceof SchemaNode)) { + continue; + } + } + if (subElement instanceof SchemaNode) { + SchemaNode rightSchemaNode = (SchemaNode) subElement; + if (!rightSchemaNode.isActive()) { + continue; + } + } + YangStatement rightSubElement = subElement; + if (contains(foundStatements, rightSubElement)) { + continue; + } + YangStatementComparator comparator = + YangComparatorRegister.getInstance().getComparator(getStatement(rightSubElement)); + compareResults.addAll(comparator.compare(null, rightSubElement)); + } + } + return compareResults; + } + +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompareType.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompareType.java new file mode 100644 index 0000000..acceac3 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompareType.java @@ -0,0 +1,23 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +public enum CompareType { + STMT, + TREE, + COMPATIBLE_CHECK +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityInfo.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityInfo.java new file mode 100644 index 0000000..c27993a --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityInfo.java @@ -0,0 +1,48 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +public class CompatibilityInfo { + private final CompatibilityRule.Compatibility compatibility; + private final String description; + + /** + * constructor. + * @param compatibility compatibility + * @param description description + */ + public CompatibilityInfo(CompatibilityRule.Compatibility compatibility, String description) { + this.compatibility = compatibility; + this.description = description; + } + + /** + * get the compatibility. + * @return compatibility. + */ + public CompatibilityRule.Compatibility getCompatibility() { + return compatibility; + } + + /** + * get the description. + * @return string. + */ + public String getDescription() { + return description; + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRule.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRule.java new file mode 100644 index 0000000..b983048 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRule.java @@ -0,0 +1,330 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.dom4j.Element; + + +public class CompatibilityRule { + private final String ruleId; + private String parentStmt; + private final List<String> statements;//[module_name:]keyword, for example, container/huawei-extension:filter + //private List<RuleType> ruleTypes;//STMT OR TREE + private final ChangeInfo condition; + private List<ChangeInfo> exceptConditions; + private final Compatibility compatibility; + private String description; + + /** + * constructor. + * + * @param ruleId rule id + * @param statements statements can be applied + * @param condition matched condition + * @param compatibility compatibility + */ + public CompatibilityRule(String ruleId, List<String> statements, ChangeInfo condition, + Compatibility compatibility) { + this.ruleId = ruleId; + this.statements = statements; + //this.ruleTypes = ruleTypes; + this.condition = condition; + this.compatibility = compatibility; + } + + /** + * get parent statement. + * + * @return statement. + */ + public String getParentStmt() { + return parentStmt; + } + + /** + * set parent statement. + * + * @param parentStmt parent statement + */ + public void setParentStmt(String parentStmt) { + this.parentStmt = parentStmt; + } + + /** + * get except conditions. + * + * @return list of change info + */ + public List<ChangeInfo> getExceptConditions() { + return exceptConditions; + } + + /** + * set except conditions. + * + * @param exceptConditions conditions + */ + public void setExceptCondition(List<ChangeInfo> exceptConditions) { + this.exceptConditions = exceptConditions; + } + + /** + * set description. + * + * @param description description. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * get rule id. + * + * @return rule id + */ + public String getRuleId() { + return ruleId; + } + + /** + * get applied statements. + * + * @return statements + */ + public List<String> getStatements() { + return statements; + } + + + /** + * get condition. + * + * @return condition + */ + public ChangeInfo getCondition() { + return condition; + } + + public Compatibility getCompatibility() { + return compatibility; + } + + /** + * get description. + * + * @return description + */ + public String getDescription() { + return description; + } + + /** + * the definition of rule type. + */ + public enum RuleType { + STMT("stmt"), + TREE("tree"); + private String name; + + private RuleType(String name) { + this.name = name; + } + + /** + * get rule type from name. + * + * @param name name + * @return rule type + */ + public static RuleType forName(String name) { + if (name.equals(STMT.name)) { + return STMT; + } else if (name.equals(TREE.name)) { + return TREE; + } + return null; + } + } + + /** + * the definition of change info. + */ + public enum ChangeInfo { + ANY("any"),//any changes, including added,deleted,changed + IGNORE("ignore"),//ignore any changes + /*any sub statement is deleted for stmt type, and any schema child node is deleted for tree type + */ + DELETED("deleted"), + /* any sub statement is added for stmt type, and any schema child node is added for tree type*/ + ADDED("added"), + MANDATORY_ADDED("mandatory-added"),// add mandatory schema node + /*the meaning has been changed,for example, builtin-type changed for type, value changed for enumeration*/ + CHANGED("changed"), + /* any sub statements sequence changed for stmt type, and any schema child nodes sequence changed for + tree type, it can be applied to any statement. + */ + SEQUENCE_CHANGED("sequence-changed"), + /*expand the scope, for range,it means larger range, for length, it means larger length, for fraction-digits, + * it means a lower value, for min-elements, it means a lower value, for max-elements, it means a higher value, + * for mandatory, it means from true to false, for config, it means from false to true + * for unique, it means one or more attributes are deleted*/ + EXPAND("expand"), + /*reduce the scope, for range,it means smaller range, for length, it means smaller length, for fraction-digits, + * it means a higher value, for min-elements, it means a higher value, for max-elements, it means a lower value, + * for mandatory, it means from false to true, for config, it means from true to false, + * for unique, it means new attributes are added */ + REDUCE("reduce"), + /* for example type from int8 to int16,it is treated non-backward-compatible default. it can be applied to + type statement*/ + INTEGER_TYPE_CHANGED("integer-type-changed"); + private String name; + + private ChangeInfo(String name) { + this.name = name; + } + + /** + * get name. + * + * @return name + */ + public String getName() { + return name; + } + + /** + * get change info from name. + * + * @param name name + * @return change info + */ + public static ChangeInfo forName(String name) { + if (name.equals(ANY.name)) { + return ANY; + } else if (name.equals(IGNORE.getName())) { + return IGNORE; + } else if (name.equals(EXPAND.getName())) { + return EXPAND; + } else if (name.equals(REDUCE.getName())) { + return REDUCE; + } else if (name.equals(CHANGED.getName())) { + return CHANGED; + } else if (name.equals(INTEGER_TYPE_CHANGED.getName())) { + return INTEGER_TYPE_CHANGED; + } else if (name.equals(SEQUENCE_CHANGED.getName())) { + return SEQUENCE_CHANGED; + } else if (name.equals(DELETED.getName())) { + return DELETED; + } else if (name.equals(ADDED.getName())) { + return ADDED; + } else if (name.equals(MANDATORY_ADDED.getName())) { + return MANDATORY_ADDED; + } + + return null; + } + + } + + /** + * the definition of compatibility. + */ + public enum Compatibility { + BC("backward-compatible"), + NBC("non-backward-compatible"), + UNKNOWN("unknown"); + private String name; + + private Compatibility(String name) { + this.name = name; + } + + /** + * get name. + * + * @return name + */ + public String getName() { + return name; + } + + /** + * get compatibility from name. + * + * @param name name + * @return compatibility + */ + public static Compatibility forName(String name) { + if (name.equals(BC.getName())) { + return BC; + } else if (name.equals(NBC.name)) { + return NBC; + } else if (name.equals(UNKNOWN.name)) { + return UNKNOWN; + } + return null; + } + } + + /** + * deserialize compatibility rule from xml. + * + * @param element xml element + * @return compatibility rule. + */ + public static CompatibilityRule deserialize(Element element) { + + Element statementsElement = element.element("statements"); + List<Element> statementElementList = statementsElement.elements("statement"); + List<String> statements = null; + if (statementElementList != null && statementElementList.size() > 0) { + statements = new ArrayList<>(); + for (Element statementElement : statementElementList) { + statements.add(statementElement.getTextTrim()); + } + } + List<RuleType> types = new ArrayList<>(); + List<Element> typeElements = element.elements("type"); + for (Element typeElement : typeElements) { + types.add(RuleType.forName(typeElement.getTextTrim())); + } + ChangeInfo condition = ChangeInfo.forName(element.elementText("condition")); + List<ChangeInfo> exceptConditions = null; + List<Element> exceptConditionElements = element.elements("except-condition"); + if (exceptConditionElements != null && exceptConditionElements.size() > 0) { + exceptConditions = new ArrayList<>(); + for (Element exceptConditionElement : exceptConditionElements) { + exceptConditions.add(ChangeInfo.forName(exceptConditionElement.getTextTrim())); + } + } + Compatibility compatibility = Compatibility.forName(element.elementText("compatible")); + String description = element.elementText("description"); + Element ruleIdElement = element.element("rule-id"); + String ruleId = ruleIdElement.getTextTrim(); + CompatibilityRule rule = new CompatibilityRule(ruleId, statements, condition, compatibility); + rule.setExceptCondition(exceptConditions); + rule.setDescription(description); + Element parentStmtElement = element.element("parent-statement"); + if (parentStmtElement != null) { + rule.setParentStmt(parentStmtElement.getTextTrim()); + } + return rule; + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRules.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRules.java new file mode 100644 index 0000000..cbab987 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRules.java @@ -0,0 +1,149 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.dom4j.Document; +import org.dom4j.Element; + +public class CompatibilityRules { + private final List<CompatibilityRule> compatibilityRules = new ArrayList<>(); + private static final CompatibilityRules instance = new CompatibilityRules(); + + private CompatibilityRules() { + + } + + /** + * add a compatibility rule. + * + * @param rule rule + * @return true or false + */ + public boolean addCompatibilityRule(CompatibilityRule rule) { + if (null != getCompatibilityRule(rule.getRuleId())) { + return false; + } + return compatibilityRules.add(rule); + } + + /** + * get compatibility rules. + * + * @return rules + */ + public List<CompatibilityRule> getCompatibilityRules() { + return compatibilityRules; + } + + /** + * get compatibility rule by specified rule id. + * + * @param ruleId rule id + * @return rule + */ + public CompatibilityRule getCompatibilityRule(String ruleId) { + for (CompatibilityRule rule : compatibilityRules) { + if (rule.getRuleId().equals(ruleId)) { + return rule; + } + } + return null; + } + + /** + * get instance of compatibility rules. + * + * @return rules instance. + */ + public static CompatibilityRules getInstance() { + return instance; + } + + /** + * deserialize from xml document. + * + * @param document xml document + */ + public void deserialize(Document document) { + compatibilityRules.clear(); + Element root = document.getRootElement(); + List<Element> children = root.elements("rule"); + for (Element ruleElement : children) { + CompatibilityRule rule = CompatibilityRule.deserialize(ruleElement); + addCompatibilityRule(rule); + } + } + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + private boolean matchCondition(CompatibilityRule left, CompatibilityRule.ChangeInfo right) { + if (left.getCondition() == CompatibilityRule.ChangeInfo.ANY) { + return true; + } else if (left.getCondition() == CompatibilityRule.ChangeInfo.IGNORE) { + return false; + } + if (left.getCondition() == right) { + return true; + } + if (left.getCondition() == CompatibilityRule.ChangeInfo.CHANGED + && (right == CompatibilityRule.ChangeInfo.EXPAND + || right == CompatibilityRule.ChangeInfo.REDUCE + || right == CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED + || right == CompatibilityRule.ChangeInfo.INTEGER_TYPE_CHANGED)) { + if (left.getExceptConditions() != null && left.getExceptConditions().contains(right)) { + return false; + } + return true; + } + return false; + } + + /** + * search rule by some arguments. + * + * @param statement statement + * @param parentStmt parent statement + * @param changeInfo change info + * @return matched rule + */ + public CompatibilityRule searchRule(String statement, String parentStmt, + CompatibilityRule.ChangeInfo changeInfo) { + for (CompatibilityRule rule : compatibilityRules) { + if (rule.getStatements().contains(statement)) { + if (rule.getParentStmt() != null) { + if (parentStmt == null) { + continue; + } + if (!rule.getParentStmt().equals(parentStmt)) { + continue; + } + } + if (matchCondition(rule, changeInfo)) { + return rule; + } + } + } + return null; + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ConfigComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ConfigComparator.java new file mode 100644 index 0000000..a0018d7 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ConfigComparator.java @@ -0,0 +1,78 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.model.api.schema.SchemaTreeType; +import org.yangcentral.yangkit.model.api.stmt.Config; +import org.yangcentral.yangkit.model.api.stmt.SchemaNode; + + +public class ConfigComparator extends CommonYangStatementComparator<Config> { + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Config left, Config right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + changeInfos.addAll(super.getChangeInfo(left, right)); + if (left.getContext().getSelf() instanceof SchemaNode) { + SchemaNode schemaNode = (SchemaNode) left.getContext().getSelf(); + if (schemaNode.getSchemaTreeType() != SchemaTreeType.DATATREE) { + changeInfos.add(CompatibilityRule.ChangeInfo.IGNORE); + return changeInfos; + } + } else if (left.getParentStatement() != null) { + if (left.getParentStatement() instanceof SchemaNode) { + SchemaNode schemaNode = (SchemaNode) left.getParentStatement(); + if (schemaNode.getSchemaTreeType() != SchemaTreeType.DATATREE) { + changeInfos.add(CompatibilityRule.ChangeInfo.IGNORE); + return changeInfos; + } + } + } + if (left.isConfig() && !right.isConfig()) { + changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE); + } else if (!left.isConfig() && right.isConfig()) { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } + + return changeInfos; + } + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Config left, Config right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "config is changed from false to true, it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DefaultComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DefaultComparator.java new file mode 100644 index 0000000..f7b1c13 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DefaultComparator.java @@ -0,0 +1,41 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.Default; + + +public class DefaultComparator extends CommonYangStatementComparator<Default> { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Default left, Default right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.DELETED + || changeInfo == CompatibilityRule.ChangeInfo.CHANGED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "delete or change default statement, it's non-backward-compatible"); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DescriptionComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DescriptionComparator.java new file mode 100644 index 0000000..2b5db1c --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DescriptionComparator.java @@ -0,0 +1,40 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.Description; + + +public class DescriptionComparator extends CommonYangStatementComparator<Description> { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Description left, Description right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "delete description statement, it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/EnumBitComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/EnumBitComparator.java new file mode 100644 index 0000000..e0fb3ef --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/EnumBitComparator.java @@ -0,0 +1,43 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + +public class EnumBitComparator extends CommonYangStatementComparator { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(YangStatement left, YangStatement right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "delete an enum, it's non-backward-compatible."); + } else if (changeInfo == CompatibilityRule.ChangeInfo.ADDED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.BC, + "add a new enum, it's backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IdentifierComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IdentifierComparator.java new file mode 100644 index 0000000..3eff979 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IdentifierComparator.java @@ -0,0 +1,40 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + +public class IdentifierComparator extends CommonYangStatementComparator { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(YangStatement left, YangStatement right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "the statement is deleted, " + + "it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IfFeatureComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IfFeatureComparator.java new file mode 100644 index 0000000..dfa0199 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IfFeatureComparator.java @@ -0,0 +1,42 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.IfFeature; + + +public class IfFeatureComparator extends CommonYangStatementComparator<IfFeature> { + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(IfFeature left, IfFeature right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.ADDED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "add a new if-feature," + + "it's non-backward-compatible."); + } else if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.UNKNOWN, + "if-feature is changed, it's compatibility is unknown."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MandatoryComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MandatoryComparator.java new file mode 100644 index 0000000..375d69b --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MandatoryComparator.java @@ -0,0 +1,63 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; +import org.yangcentral.yangkit.model.api.stmt.Mandatory; + + +public class MandatoryComparator extends CommonYangStatementComparator<Mandatory> { + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Mandatory left, Mandatory right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + + if (left.getValue() && !right.getValue()) { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } else if (!left.getValue() && right.getValue()) { + changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE); + } + if (super.getChangeInfo(left, right).contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) { + changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED); + } + return changeInfos; + } + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Mandatory left, Mandatory right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "mandatory is changed from false to true," + + "it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MaxElementsComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MaxElementsComparator.java new file mode 100644 index 0000000..1361ef2 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MaxElementsComparator.java @@ -0,0 +1,69 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.model.api.stmt.MaxElements; + + +public class MaxElementsComparator extends CommonYangStatementComparator<MaxElements> { + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(MaxElements left, MaxElements right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + if (left.isUnbounded() && !right.isUnbounded()) { + changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE); + } else if (!left.isUnbounded() && right.isUnbounded()) { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } else if (!left.isUnbounded() && !right.isUnbounded()) { + if (left.getValue() < right.getValue()) { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } else if (left.getValue() > right.getValue()) { + changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE); + } + } + if (super.getChangeInfo(left, right).contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) { + changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED); + } + return changeInfos; + } + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(MaxElements left, MaxElements right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "the max-elements is reduced," + + "it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MinElementsComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MinElementsComparator.java new file mode 100644 index 0000000..f97e313 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MinElementsComparator.java @@ -0,0 +1,63 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.model.api.stmt.MinElements; + + +public class MinElementsComparator extends CommonYangStatementComparator<MinElements> { + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(MinElements left, MinElements right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + if (left.getValue() > right.getValue()) { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } else if (left.getValue() < right.getValue()) { + changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE); + } + if (super.getChangeInfo(left, right).contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) { + changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED); + } + return changeInfos; + } + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(MinElements left, MinElements right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "min-elements is increased," + + "it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ModuleComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ModuleComparator.java new file mode 100644 index 0000000..9c9bb7f --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ModuleComparator.java @@ -0,0 +1,86 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; +import org.yangcentral.yangkit.model.api.stmt.MainModule; +import org.yangcentral.yangkit.model.api.stmt.Module; + + + +public class ModuleComparator extends CommonYangStatementComparator<Module> { + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Module left, Module right) { + return super.getChangeInfo(left, right); + } + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Module left, Module right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.DELETED + || changeInfo == CompatibilityRule.ChangeInfo.CHANGED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "delete a module or change module name," + + "it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<YangCompareResult> compareChildren(Module left, Module right) { + List<YangCompareResult> results = new ArrayList<>(); + Module temp = left; + if (temp == null) { + temp = right; + } + results.addAll(compareStatements(left == null ? new ArrayList<>() : left.getEffectiveMetaStatements(), + right == null ? new ArrayList<>() : right.getEffectiveMetaStatements(), OPTION_ALL)); + results.addAll(compareStatements(left == null ? new ArrayList<>() : left.getEffectiveLinkageStatement(), + right == null ? new ArrayList<>() : right.getEffectiveLinkageStatement(), OPTION_ALL)); + if (temp instanceof MainModule) { + results.addAll(compareStatements(left == null ? new ArrayList<>() : left.getEffectiveDefinitionStatement(), + right == null ? new ArrayList<>() : right.getEffectiveDefinitionStatement(), OPTION_ONLY_META)); + results.addAll(compareStatements( + left == null ? new ArrayList<>() : YangComparator.getEffectiveSchemaNodeChildren(left), + right == null ? new ArrayList<>() : YangComparator.getEffectiveSchemaNodeChildren(right), + OPTION_ONLY_SCHEMA)); + } + return results; + } + + +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/NamespaceComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/NamespaceComparator.java new file mode 100644 index 0000000..8ea9953 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/NamespaceComparator.java @@ -0,0 +1,39 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.Namespace; + + +public class NamespaceComparator extends CommonYangStatementComparator<Namespace> { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Namespace left, Namespace right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "namespace MUST NOT be changed."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/OperationComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/OperationComparator.java new file mode 100644 index 0000000..58cde02 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/OperationComparator.java @@ -0,0 +1,90 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.model.api.stmt.Operation; +import org.yangcentral.yangkit.model.api.stmt.SchemaNode; +import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer; +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + + +public class OperationComparator extends SchemaNodeComparator<Operation> { + + /** + * + * @param schemaNodeContainer + * @return + */ + private boolean hasActiveSchemaChildren(SchemaNodeContainer schemaNodeContainer) { + for (SchemaNode schemaNode : schemaNodeContainer.getSchemaNodeChildren()) { + if (schemaNode.isActive()) { + return true; + } + } + return false; + } + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<YangCompareResult> compareChildren(Operation left, Operation right) { + List<YangCompareResult> compareResults = new ArrayList<>(); + compareResults.addAll(compareStatements(left == null ? new ArrayList<>() : left.getEffectiveSubStatements(), + right == null ? new ArrayList<>() : right.getEffectiveSubStatements(), OPTION_ONLY_META)); + + + List<YangStatement> leftSchemaChildren = new ArrayList<>(); + List<YangStatement> rightSchemaChildren = new ArrayList<>(); + //input + if (left.getInput() != null && left.getInput().isActive()) { + //check input's schema children, only more than zero can be add to left schema array + if (hasActiveSchemaChildren(left.getInput())) { + leftSchemaChildren.add(left.getInput()); + } + } + if (right.getInput() != null && right.getInput().isActive()) { + //check input's schema children, only more than zero can be add to right schema array + if (hasActiveSchemaChildren(right.getInput())) { + rightSchemaChildren.add(right.getInput()); + } + } + //output + if (left.getOutput() != null && left.getOutput().isActive()) { + //check output's schema children, only more than zero can be add to left schema array + if (hasActiveSchemaChildren(left.getOutput())) { + leftSchemaChildren.add(left.getOutput()); + } + } + if (right.getOutput() != null && right.getOutput().isActive()) { + //check out's schema children, only more than zero can be add to right schema array + if (hasActiveSchemaChildren(right.getOutput())) { + rightSchemaChildren.add(right.getOutput()); + } + } + compareResults.addAll(compareStatements(leftSchemaChildren, rightSchemaChildren, OPTION_ALL)); + return compareResults; + } +} + diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/PatternComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/PatternComparator.java new file mode 100644 index 0000000..83f3f9b --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/PatternComparator.java @@ -0,0 +1,43 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.type.Pattern; + + +public class PatternComparator extends CommonYangStatementComparator<Pattern> { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Pattern left, Pattern right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.ADDED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "add a pattern, it's non-backward-compatible."); + } else if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.UNKNOWN, + "change a pattern, the compatibility is unknown."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/RangeLengthComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/RangeLengthComparator.java new file mode 100644 index 0000000..076b7bf --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/RangeLengthComparator.java @@ -0,0 +1,67 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.model.api.stmt.type.SectionExpression; + + +public class RangeLengthComparator extends CommonYangStatementComparator<SectionExpression> { + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(SectionExpression left, SectionExpression right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + if (!left.equals(right)) { + if (left.isSubSet(right)) { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } else if (right.isSubSet(left)) { + changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE); + } + } + + List<CompatibilityRule.ChangeInfo> superChangeInfos = super.getChangeInfo(left, right); + if (superChangeInfos.contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) { + changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED); + } + return changeInfos; + } + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(SectionExpression left, SectionExpression right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "the range or length is reduced, " + + "it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ReferenceComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ReferenceComparator.java new file mode 100644 index 0000000..be50fa1 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ReferenceComparator.java @@ -0,0 +1,40 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.Reference; + + +public class ReferenceComparator extends CommonYangStatementComparator<Reference> { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Reference left, Reference right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "delete reference, it;s non-backward-compatible"); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/SchemaNodeComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/SchemaNodeComparator.java new file mode 100644 index 0000000..ff6de53 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/SchemaNodeComparator.java @@ -0,0 +1,182 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.model.api.stmt.SchemaNode; +import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer; + + + +public class SchemaNodeComparator<T extends SchemaNode> extends CommonYangStatementComparator<T> { + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(T left, T right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + if (left == null && right != null) { + if (right.isMandatory()) { + changeInfos.add(CompatibilityRule.ChangeInfo.MANDATORY_ADDED); + } else { + changeInfos.add(CompatibilityRule.ChangeInfo.ADDED); + } + } else if (left != null && right == null) { + changeInfos.add(CompatibilityRule.ChangeInfo.DELETED); + } else if (left != null && right != null) { + changeInfos.addAll(super.getChangeInfo(left, right)); + } + return changeInfos; + } + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(T left, T right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.MANDATORY_ADDED + || changeInfo == CompatibilityRule.ChangeInfo.DELETED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, null); + } + return super.defaultCompatibility(left, right, changeInfo); + } + + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<YangCompareResult> compareChildren(T left, T right) { + List<YangCompareResult> results = new ArrayList<>(); + results.addAll(super.compareChildren(left, right)); + + SchemaNode temp = left; + if (temp == null) { + temp = right; + } + if ((temp instanceof SchemaNodeContainer)) { + SchemaNodeContainer leftContainer = (SchemaNodeContainer) left; + SchemaNodeContainer rightContainer = (SchemaNodeContainer) right; + results.addAll(compareStatements(leftContainer == null ? new ArrayList<>() : + YangComparator.getEffectiveSchemaNodeChildren(leftContainer), + rightContainer == null ? new ArrayList<>() : + YangComparator.getEffectiveSchemaNodeChildren(rightContainer), OPTION_ONLY_SCHEMA)); + } + return results; + } + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + public List<YangCompareResult> compare(T left, T right) { + List<YangCompareResult> compareResults = new ArrayList<>(); + if (left == null && right == null) { + return compareResults; + } + List<CompatibilityRule.ChangeInfo> changeInfos = getChangeInfo(left, right); + List<YangTreeCompareResult> treeCompareResults = new ArrayList<>(); + SchemaNode temp = right; + if (temp == null) { + temp = left; + } + String statement = getStatement(temp); + String parentStatement = getStatement(temp.getParentStatement()); + if (!changeInfos.isEmpty()) { + for (CompatibilityRule.ChangeInfo changeInfo : changeInfos) { + + CompatibilityRule compatibilityRule = null; + if (getCompatibilityRules() != null) { + compatibilityRule = getCompatibilityRules().searchRule(statement, parentStatement, changeInfo); + } + if (compatibilityRule == null) { + if (changeInfo == CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED) { + continue; + } + YangTreeCompareResult treeCompareResult = + new YangTreeCompareResult(temp.getSchemaPath(), getChangeType(changeInfo)); + treeCompareResult.setLeft(left); + treeCompareResult.setRight(right); + treeCompareResult.setCompatibilityInfo(defaultCompatibility(left, right, changeInfo)); + treeCompareResults.add(treeCompareResult); + } else { + YangTreeCompareResult treeCompareResult = + new YangTreeCompareResult(temp.getSchemaPath(), getChangeType(changeInfo)); + treeCompareResult.setLeft(left); + treeCompareResult.setRight(right); + treeCompareResult.setCompatibilityInfo(new CompatibilityInfo(compatibilityRule.getCompatibility(), + compatibilityRule.getDescription())); + treeCompareResults.add(treeCompareResult); + } + } + compareResults.addAll(treeCompareResults); + } + + //sub statements + if (left != null && right != null) { + List<YangCompareResult> childrenResults = compareChildren(left, right); + for (YangCompareResult childResult : childrenResults) { + if (childResult instanceof YangStatementCompareResult) { + if (treeCompareResults.isEmpty()) { + YangTreeCompareResult treeCompareResult = + new YangTreeCompareResult(temp.getSchemaPath(), ChangeType.MODIFY); + treeCompareResult.setLeft(left); + treeCompareResult.setRight(right); + treeCompareResult.setCompatibilityInfo( + new CompatibilityInfo(CompatibilityRule.Compatibility.BC, null)); + treeCompareResults.add(treeCompareResult); + compareResults.add(treeCompareResult); + } + for (YangTreeCompareResult treeCompareResult : treeCompareResults) { + treeCompareResult.addMetaCompareResult(childResult); + if (childResult.getCompatibilityInfo().getCompatibility() + == CompatibilityRule.Compatibility.NBC) { + treeCompareResult.setCompatibilityInfo( + new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, null)); + } else if (childResult.getCompatibilityInfo().getCompatibility() + == CompatibilityRule.Compatibility.UNKNOWN) { + if (treeCompareResult.getCompatibilityInfo().getCompatibility() + == CompatibilityRule.Compatibility.BC) { + treeCompareResult.setCompatibilityInfo( + new CompatibilityInfo(CompatibilityRule.Compatibility.UNKNOWN, null)); + } + } + } + } else { + compareResults.add(childResult); + } + } + } + return compareResults; + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/StatusComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/StatusComparator.java new file mode 100644 index 0000000..8a6df4d --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/StatusComparator.java @@ -0,0 +1,73 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; +import org.yangcentral.yangkit.model.api.stmt.Status; +import org.yangcentral.yangkit.model.api.stmt.StatusStmt; + + + + +public class StatusComparator extends CommonYangStatementComparator<StatusStmt> { + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(StatusStmt left, StatusStmt right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + if (!left.equals(right)) { + if (left.getStatus() == Status.CURRENT) { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } else if (left.getStatus() == Status.DEPRECATED && right.getStatus() == Status.OBSOLETE) { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } else { + changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE); + } + } + List<CompatibilityRule.ChangeInfo> superChangeInfos = super.getChangeInfo(left, right); + if (superChangeInfos.contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) { + changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED); + } + return changeInfos; + } + + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(StatusStmt left, StatusStmt right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "un-acceptable change of status," + + "changed from current to deprecated or obsolete and changed from deprecated " + + "to obsolete ard acceptable."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/TypeStatementComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/TypeStatementComparator.java new file mode 100644 index 0000000..d934cfb --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/TypeStatementComparator.java @@ -0,0 +1,122 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.model.api.restriction.YangInteger; +import org.yangcentral.yangkit.model.api.stmt.Type; +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + + +/** + * comparator for type statement. + * + * @since 2022-06-10 + */ +public class TypeStatementComparator extends CommonYangStatementComparator<Type> { + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Type left, Type right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + if (left == null && right != null) { + changeInfos.add(CompatibilityRule.ChangeInfo.ADDED); + return changeInfos; + } else if (left != null && right == null) { + changeInfos.add(CompatibilityRule.ChangeInfo.DELETED); + return changeInfos; + } else if (left == null && right == null) { + return changeInfos; + } + if (left.getRestriction().getClass() == right.getRestriction().getClass()) { + return changeInfos; + } + if (left.getRestriction().getClass() != right.getRestriction().getClass()) { + if ((left.getRestriction() instanceof YangInteger) && (right.getRestriction() instanceof YangInteger)) { + changeInfos.add(CompatibilityRule.ChangeInfo.INTEGER_TYPE_CHANGED); + } else { + if (!changeInfos.contains(CompatibilityRule.ChangeInfo.CHANGED)) { + changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED); + } + } + } + return changeInfos; + } + + @Override + public List<YangCompareResult> compare(Type left, Type right) { + List<YangCompareResult> compareResults = new ArrayList<>(); + List<CompatibilityRule.ChangeInfo> changeInfos = getChangeInfo(left, right); + + if (!changeInfos.isEmpty()) { + YangStatement effectiveStmt = left == null ? right : left; + String statement = getStatement(effectiveStmt); + String parentStmt = getStatement(effectiveStmt.getParentStatement()); + for (CompatibilityRule.ChangeInfo changeInfo : changeInfos) { + CompatibilityRule compatibilityRule = null; + if (getCompatibilityRules() != null) { + compatibilityRule = getCompatibilityRules().searchRule(statement, parentStmt, changeInfo); + } + if (compatibilityRule == null) { + if (changeInfo == CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED) { + continue; + } + YangStatementCompareResult statementCompareResult = + new YangStatementCompareResult(getChangeType(changeInfo), left, right); + statementCompareResult.setCompatibilityInfo(defaultCompatibility(left, right, changeInfo)); + compareResults.add(statementCompareResult); + } else { + YangStatementCompareResult statementCompareResult = + new YangStatementCompareResult(getChangeType(changeInfo), left, right); + statementCompareResult.setCompatibilityInfo( + new CompatibilityInfo(compatibilityRule.getCompatibility(), + compatibilityRule.getDescription())); + compareResults.add(statementCompareResult); + } + + } + } + + //sub statements + if (left != null && right != null) { + if (left.getRestriction().getClass() != right.getRestriction().getClass()) { + if ((left.getRestriction() instanceof YangInteger) && (right.getRestriction() instanceof YangInteger)) { + compareResults.addAll(compareChildren(left, right)); + } + } else { + compareResults.addAll(compareChildren(left, right)); + } + + } + return compareResults; + } + + @Override + protected CompatibilityInfo defaultCompatibility(Type left, Type right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED + || changeInfo == CompatibilityRule.ChangeInfo.INTEGER_TYPE_CHANGED + || changeInfo == CompatibilityRule.ChangeInfo.DELETED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, null); + } + + return super.defaultCompatibility(left, right, changeInfo); + } + + +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UniqueComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UniqueComparator.java new file mode 100644 index 0000000..1611818 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UniqueComparator.java @@ -0,0 +1,105 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import java.util.ArrayList; +import java.util.List; +import org.yangcentral.yangkit.model.api.stmt.Leaf; +import org.yangcentral.yangkit.model.api.stmt.Unique; +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + +public class UniqueComparator extends CommonYangStatementComparator<Unique> { + + /** + * + * @param left left statement + * @param right right statement + * @return + */ + @Override + protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Unique left, Unique right) { + List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>(); + if (left == null && right != null) { + changeInfos.add(CompatibilityRule.ChangeInfo.ADDED); + } else if (left != null && right == null) { + changeInfos.add(CompatibilityRule.ChangeInfo.DELETED); + } else { + if (!left.equals(right)) { + int leftSize = left.getUniqueNodes().size(); + int rightSize = right.getUniqueNodes().size(); + if (leftSize == rightSize) { + changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED); + } else if (leftSize < rightSize) { + boolean notfind = false; + for (int i = 0; i < leftSize; i++) { + Leaf leftUnique = left.getUniqueNodes().get(i); + List<YangStatement> rightUniques = new ArrayList<>(); + for (Leaf rightUnique : right.getUniqueNodes()) { + rightUniques.add(rightUnique); + } + if (searchStatement(leftUnique, rightUniques, new ArrayList<>()) == null) { + notfind = true; + } + } + if (notfind) { + changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED); + } else { + changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE); + } + } else { + boolean notfind = false; + for (int i = 0; i < rightSize; i++) { + Leaf rightUnique = right.getUniqueNodes().get(i); + List<YangStatement> leftUniques = new ArrayList<>(); + for (Leaf leftUnique : left.getUniqueNodes()) { + leftUniques.add(leftUnique); + } + if (searchStatement(rightUnique, leftUniques, new ArrayList<>()) == null) { + notfind = true; + } + } + if (notfind) { + changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED); + } else { + changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND); + } + } + } + } + + return changeInfos; + } + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Unique left, Unique right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.ADDED + || changeInfo == CompatibilityRule.ChangeInfo.REDUCE) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "add new unique or add a new node on unique is non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UnitsComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UnitsComparator.java new file mode 100644 index 0000000..f484af2 --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UnitsComparator.java @@ -0,0 +1,41 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.Units; + + +public class UnitsComparator extends CommonYangStatementComparator<Units> { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(Units left, Units right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.DELETED + || changeInfo == CompatibilityRule.ChangeInfo.CHANGED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "delete or change units, it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ValuePositionComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ValuePositionComparator.java new file mode 100644 index 0000000..c680dea --- /dev/null +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ValuePositionComparator.java @@ -0,0 +1,39 @@ +/* +Copyright 2023 Huawei Technologies + +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.onap.modeling.yangkit.comparator; + +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + +public class ValuePositionComparator extends CommonYangStatementComparator { + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ + @Override + protected CompatibilityInfo defaultCompatibility(YangStatement left, YangStatement right, + CompatibilityRule.ChangeInfo changeInfo) { + if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED) { + return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, + "change value or position, it's non-backward-compatible."); + } + return super.defaultCompatibility(left, right, changeInfo); + } +} diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java index cc6992a..3825a74 100644 --- a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java @@ -19,6 +19,14 @@ package org.onap.modeling.yangkit.comparator; import org.yangcentral.yangkit.model.api.stmt.YangStatement; public class WhenMustComparator extends CommonYangStatementComparator { + + /** + * + * @param left left statement + * @param right right statement + * @param changeInfo + * @return + */ @Override protected CompatibilityInfo defaultCompatibility(YangStatement left, YangStatement right, CompatibilityRule.ChangeInfo changeInfo) { |