Skip to content

Commit

Permalink
[yang] Support for groupings, uses and identities #1221 (#1224)
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian-Mueller-GIP authored Nov 7, 2024
1 parent 2937703 commit e3a8994
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 46 deletions.
2 changes: 1 addition & 1 deletion modules/xdev/yang/application.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--><Application applicationName="YangAppGenerator" comment="" factoryVersion="" versionName="0.1.2" xmlVersion="1.1">
--><Application applicationName="YangAppGenerator" comment="" factoryVersion="" versionName="0.1.3" xmlVersion="1.1">
<ApplicationInfo>
<RuntimeContextRequirements>
<RuntimeContextRequirement>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public class Constants {
public static final String TYPE_CONTAINER = "container";
public static final String TYPE_LEAF = "leaf";
public static final String TYPE_GROUPING = "grouping";
public static final String TYPE_USES = "uses";
public static final String TYPE_IDENTITY = "identity";

public static final String NS_SEPARATOR = "§";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Copyright 2024 Xyna GmbH, Germany
*
* 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 xdev.yang.impl;



import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.yangcentral.yangkit.base.YangElement;
import org.yangcentral.yangkit.model.api.stmt.Container;
import org.yangcentral.yangkit.model.api.stmt.Leaf;
import org.yangcentral.yangkit.model.api.stmt.Uses;
import org.yangcentral.yangkit.model.api.stmt.YangStatement;



public class YangStatementTranslator {

public static final Map<Class<?>, YangStatementTranslation> translations = setupStatementTranslations();


private static Map<Class<?>, YangStatementTranslation> setupStatementTranslations() {
Map<Class<?>, YangStatementTranslation> result = new HashMap<Class<?>, YangStatementTranslation>();
result.put(Container.class, new YangStatementTranslation(Constants.TYPE_CONTAINER));
result.put(Leaf.class, new YangStatementTranslation(Constants.TYPE_LEAF));
result.put(Uses.class, new YangStatementTranslation(Constants.TYPE_USES));
return result;
}


public static YangStatementTranslation getTranslation(Class<?> yangStatementClass) {
return translations.get(yangStatementClass);
}


public static class YangStatementTranslation {

private String yangStatementName;


public YangStatementTranslation(String yangStatementName) {
this.yangStatementName = yangStatementName;

}


public String getYangStatementName() {
return yangStatementName;
}


public static String getLocalName(YangStatement statement) {
return statement.getArgStr();
}


public static String getUriString(YangStatement statement) {
return statement.getContext().getNamespace().getUri().toString();
}


public static List<YangElement> getSubStatements(YangStatement statement) {
if (statement instanceof Uses) {
return ((Uses) statement).getRefGrouping().getSubElements();
} else {
return statement.getSubElements();
}
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ private void createMappingImpl(StringBuilder result, UseCaseMapping mapping, Lis
result.append("\n//").append(mapping.getMappingYangPath()).append(" -> ").append(mapping.getValue()).append("\n");

List<Pair<String, String>> mappingList = mapping.createPathList();
mappingList.removeIf(x -> x.getFirst().startsWith("uses:")); // remove tags <uses:grouping_name> in the mapping implementation
int insertIndex = 0;
for (int i = 0; i < position.size(); i++) {
if (mappingList.size() < i) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,21 @@
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Objects;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.yangcentral.yangkit.base.YangElement;
import org.yangcentral.yangkit.model.api.schema.YangSchemaContext;
import org.yangcentral.yangkit.model.api.stmt.Container;
import org.yangcentral.yangkit.model.api.stmt.Grouping;
import org.yangcentral.yangkit.model.api.stmt.Input;
import org.yangcentral.yangkit.model.api.stmt.Leaf;
import org.yangcentral.yangkit.model.api.stmt.Module;
import org.yangcentral.yangkit.model.api.stmt.Rpc;
import org.yangcentral.yangkit.model.api.stmt.SchemaNode;
import org.yangcentral.yangkit.model.api.stmt.YangStatement;
import org.yangcentral.yangkit.parser.YangYinParser;

import com.gip.xyna.XynaFactory;
import com.gip.xyna.utils.collections.Pair;
import com.gip.xyna.utils.exceptions.XynaException;
Expand All @@ -63,32 +56,16 @@
import xact.http.enums.httpmethods.POST;
import xdev.yang.impl.Constants;
import xdev.yang.impl.XmomDbInteraction;
import xdev.yang.impl.YangStatementTranslator;
import xdev.yang.impl.YangStatementTranslator.YangStatementTranslation;
import xmcp.yang.LoadYangAssignmentsData;
import xmcp.yang.UseCaseAssignmentTableData;
import xmcp.yang.YangDevice;
import xmcp.yang.YangModuleCollection;

public class UseCaseAssignmentUtils {

private static final Set<Class<?>> supportedYangStatementsForAssignments = setupSupportedAssignmentClasses();
private static final Map<Class<?>, String> yangStatementIdentifiers = setupStatementIdentifiers();

private static Set<Class<?>> setupSupportedAssignmentClasses() {
Set<Class<?>> result = new HashSet<Class<?>>();
result.add(Container.class);
result.add(Leaf.class);
result.add(Grouping.class);
return result;
}

private static Map<Class<?>, String> setupStatementIdentifiers() {
Map<Class<?>, String> result = new HashMap<Class<?>, String>();
result.put(Container.class, Constants.TYPE_CONTAINER);
result.put(Leaf.class, Constants.TYPE_LEAF);
result.put(Grouping.class, Constants.TYPE_GROUPING);
return result;
}

public static List<UseCaseAssignmentTableData> loadPossibleAssignments(List<Module> modules, String rpcName, String rpcNs, LoadYangAssignmentsData data) {
Rpc rpc = findRpc(modules, rpcName, rpcNs);
Input input = rpc.getInput();
Expand All @@ -106,10 +83,10 @@ private static List<YangStatement> traverseYang(List<Module> modules, String pat
}
return getCandidates(element);
}


private static List<YangStatement> getCandidates(YangStatement statement) {
List<YangElement> candidates = statement.getSubElements();
List<YangElement> candidates = YangStatementTranslation.getSubStatements(statement);
List<YangStatement> result = new ArrayList<>();
for (YangElement candidate : candidates) {
if (isSupportedElement(candidate)) {
Expand All @@ -118,19 +95,19 @@ private static List<YangStatement> getCandidates(YangStatement statement) {
}
return result;
}



private static YangStatement traverseYangOneLayer(List<Module> modules, String pathStep, String namespace, YangStatement statement) {
List<YangElement> candidates = statement.getSubElements();
for(YangElement candidate : candidates) {
if(isSupportedElement(candidate)) {
SchemaNode node = (SchemaNode) candidate;
if (node.getIdentifier().getLocalName().equals(pathStep)
&& Objects.equals(node.getContext().getNamespace().getUri().toString(), namespace)) {
return (YangStatement) candidate;
List<YangElement> candidates = YangStatementTranslation.getSubStatements(statement);
for (YangElement candidate : candidates) {
if (isSupportedElement(candidate)) {
YangStatement node = (YangStatement) candidate;
if (YangStatementTranslation.getLocalName(node).equals(pathStep)
&& Objects.equals(YangStatementTranslation.getUriString(node), namespace)) {
return node;
}
}
}

throw new RuntimeException("Could not traverse from " + statement.getArgStr() + " to " + pathStep);
}

Expand All @@ -139,8 +116,8 @@ private static List<UseCaseAssignmentTableData> loadAssignments(List<YangStateme
List<UseCaseAssignmentTableData> result = new ArrayList<>();
for (YangStatement element : subElements) {
if (isSupportedElement(element)) {
String localName = ((SchemaNode) element).getIdentifier().getLocalName();
String namespace = element.getContext().getNamespace().getUri().toString();
String localName = YangStatementTranslation.getLocalName(element);
String namespace = YangStatementTranslation.getUriString(element);
UseCaseAssignmentTableData.Builder builder = new UseCaseAssignmentTableData.Builder();
LoadYangAssignmentsData updatedData = data.clone();
updatedData.unversionedSetTotalYangPath(updatedData.getTotalYangPath() + "/" + localName);
Expand All @@ -153,21 +130,21 @@ private static List<UseCaseAssignmentTableData> loadAssignments(List<YangStateme
}
return result;
}


private static boolean isSupportedElement(YangElement element) {
for (Class<?> c : supportedYangStatementsForAssignments) {
if (c.isAssignableFrom(element.getClass())) {
for (Entry<Class<?>, YangStatementTranslation> c: YangStatementTranslator.translations.entrySet()) {
if (c.getKey().isAssignableFrom(element.getClass())) {
return true;
}
}
return false;
}

private static String getYangType(YangElement element) {
for(Entry<Class<?>, String> c : yangStatementIdentifiers.entrySet()) {
for(Entry<Class<?>, YangStatementTranslation> c : YangStatementTranslator.translations.entrySet()) {
if(c.getKey().isAssignableFrom(element.getClass())) {
return c.getValue();
return c.getValue().getYangStatementName();
}
}
return "Unknown: " + element.getClass().getCanonicalName();
Expand Down

0 comments on commit e3a8994

Please sign in to comment.