Commit fb012019 authored by Philip Makedonski's avatar Philip Makedonski
Browse files

+ added initial mappings (WIP), other refinements (unions, enums, constraints)

* updated upstream api to latest version
parent a3b7c10a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ public class YANGConverter {
//		inputPath = "samples/simple/example.yang";
//		inputPath = "samples/simple/acme.yang";
		inputPath = "samples/simple";
		inputPath = "samples";
//		inputPath = "samples";
		String output = processToString(inputPath, inputPath+".tdltx");
		System.out.println(output);
	}
+115 −11
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package org.etsi.mts.tdl.yang2tdl;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
@@ -10,9 +11,13 @@ import java.util.stream.Collectors;

import org.eclipse.core.resources.IProject;
import org.etsi.mts.tdl.CollectionDataType;
import org.etsi.mts.tdl.Constraint;
import org.etsi.mts.tdl.ConstraintType;
import org.etsi.mts.tdl.DataElementMapping;
import org.etsi.mts.tdl.DataType;
import org.etsi.mts.tdl.EnumDataType;
import org.etsi.mts.tdl.Extension;
import org.etsi.mts.tdl.LiteralValueUse;
import org.etsi.mts.tdl.Member;
import org.etsi.mts.tdl.SimpleDataInstance;
import org.etsi.mts.tdl.SimpleDataType;
@@ -29,18 +34,23 @@ import org.opendaylight.yangtools.yang.model.api.ContainerLike;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ElementCountConstraint;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
import org.opendaylight.yangtools.yang.model.api.type.LengthRestrictedTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
import org.opendaylight.yangtools.yang.model.ri.type.BaseTypes;
import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.DeclaredCaseEffectiveStatement;
import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.EmptyChoiceEffectiveStatement;
@@ -52,6 +62,8 @@ import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.RegularLeafListEff
import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.SlimLeafListEffectiveStatement;
import org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff.UndeclaredCaseEffectiveStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.Default;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
import org.opendaylight.yangtools.yang.model.spi.source.FileYangTextSource;
import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors;
@@ -74,7 +86,6 @@ public class Yang2TDLTranslator extends AbstractTranslator {
	//inherited entry point
	@Override
	public void translate(String targetFilename) throws Exception {
		String sourceMappingTag = "SOURCE_MAPPING";
		drm = getTypeFor(sourceMappingTag, tdlPackage.Literals.DATA_RESOURCE_MAPPING);
		drm.setResourceURI(new File(targetFilename).getName());
		
@@ -143,6 +154,9 @@ public class Yang2TDLTranslator extends AbstractTranslator {
		//TODO: include meta-data -> need to sort out multipe annotations
		//TODO: library of built-in types
		//TODO: add extensions
		drmTarget = getTypeFor(targetMappingTag, tdlPackage.Literals.DATA_RESOURCE_MAPPING);
//		mappingsPackage.getPackagedElement().add(drmTarget);
		drmTarget.setResourceURI("TODO");
		translate(schemaContext);
	}

@@ -175,6 +189,7 @@ public class Yang2TDLTranslator extends AbstractTranslator {
		if (parent != null) {
			name = parent+"___"+name;
		}
		System.out.println(name);
		if (c instanceof ContainerSchemaNode) {
			//DONE: remove wrapper container structured data type of only a collection is contained
			Collection<? extends DataSchemaNode> childNodes = ((ContainerSchemaNode) c).getChildNodes();
@@ -190,6 +205,7 @@ public class Yang2TDLTranslator extends AbstractTranslator {
		} else if (c instanceof ListSchemaNode) {
			StructuredDataType itemType = translateStructuredDataType((ListSchemaNode) c, baseName, name);
			CollectionDataType collectionType = getCollectionDataTypeFor(itemType);
			addMapping(c.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), collectionType, sourceMappingTag, targetMappingTag);

			//TODO: add key annotation?
			List<QName> keyDefinition = ((ListSchemaNode) c).getKeyDefinition();
@@ -198,6 +214,22 @@ public class Yang2TDLTranslator extends AbstractTranslator {
					.collect(Collectors.joining(", "));
			// TODO: make optional
//			annotateWith(collectionType, LIST_KEY, key);
			
			//TODO: add max count constraint
			((ListSchemaNode) c).getElementCountConstraint().ifPresent(cs -> {
				//TODO: extract
				Integer value = cs.getMaxElements();
				String constraintName = "maxLength";
				if (value == null) {
					value = cs.getMinElements();
					constraintName = "minLength";
				}
				Constraint constraint = constrainWith(collectionType, constraintName);
				LiteralValueUse ut = tdlFactory.eINSTANCE.createLiteralValueUse();
				ut.setIntValue(BigInteger.valueOf(value.longValue()));
				constraint.getQuantifier().add(ut);
			});
			
			return collectionType;
		} else if (c instanceof RegularLeafListEffectiveStatement) {
			//TODO: what is the difference?
@@ -222,6 +254,7 @@ public class Yang2TDLTranslator extends AbstractTranslator {
			//TODO: what is the difference? is it used
			String typeName = ((RegularLeafEffectiveStatement) c).getType().getQName().getLocalName();
			SimpleDataType dataType = getSimpleDataTypeFor(typeName);
			addMapping(c.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), dataType, sourceMappingTag, targetMappingTag);
			return dataType;
		} else if (c instanceof RegularChoiceEffectiveStatement) {
			//TODO: difference?
@@ -229,6 +262,7 @@ public class Yang2TDLTranslator extends AbstractTranslator {
			for (CaseSchemaNode child : ((RegularChoiceEffectiveStatement) c).getCases()) {
				translateMember(baseName, dataType, child);
			}
			addMapping(c.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), dataType, sourceMappingTag, targetMappingTag);
			return dataType;
		} else if (c instanceof EmptyChoiceEffectiveStatement) {
			//TODO: add annotation choice
@@ -238,6 +272,7 @@ public class Yang2TDLTranslator extends AbstractTranslator {
			for (CaseSchemaNode child : ((EmptyChoiceEffectiveStatement) c).getCases()) {
				translateMember(baseName, dataType, child);
			}
			addMapping(c.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), dataType, sourceMappingTag, targetMappingTag);
			return dataType;
		} else if (c instanceof UndeclaredCaseEffectiveStatement) {
			//choice -> container? (no case)
@@ -256,6 +291,7 @@ public class Yang2TDLTranslator extends AbstractTranslator {
	private CollectionDataType translateSimpleDataCollection(String name, TypeDefinition<?> type) {
		SimpleDataType itemType = translateSimpleDataType(name, type);
		CollectionDataType collectionType = getCollectionDataTypeFor(itemType);
		addMapping(type.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), collectionType, sourceMappingTag, targetMappingTag);
		return collectionType;
	}

@@ -276,12 +312,43 @@ public class Yang2TDLTranslator extends AbstractTranslator {
			//DONE: handle enumeration -> add instances rather than extension
			EnumDataType dataType = getEnumDataTypeFor(typeName);
			for (EnumPair e : ((EnumTypeDefinition)baseType).getValues()) {
				SimpleDataInstance eInstance = getSimpleDataInstanceFor(e.getName());
				SimpleDataInstance eInstance = getEnumDataInstanceFor(e.getName(), dataType);
				eInstance.setDataType(dataType);
				dataType.getValue().add(eInstance);
			}
			addMapping(type.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), dataType, sourceMappingTag, targetMappingTag);

			//TODO: add default?
			return dataType;
			//TODO: union of simple data types? also enums?
			//TODO: adapt further?
		} else if (type instanceof EnumTypeDefinition) {
			EnumDataType dataType = getEnumDataTypeFor(name);
			for (EnumPair e : ((EnumTypeDefinition)type).getValues()) {
				SimpleDataInstance eInstance = getEnumDataInstanceFor(e.getName(), dataType);
				eInstance.setDataType(dataType);
				dataType.getValue().add(eInstance);
			}
			addMapping(type.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), dataType, sourceMappingTag, targetMappingTag);

			return dataType;
		} else if (type instanceof UnionTypeDefinition) {
			SimpleDataType dataType = getSimpleDataTypeFor(name);
			//dataType.setName(type.getQName().getLocalName());
			List<TypeDefinition<?>> types = ((UnionTypeDefinition) type).getTypes();
			Constraint constraint = constrainWith(dataType, "union");
			if (constraint != null) {
				for (TypeDefinition<?>t : types) {
					SimpleDataType unionType = translateSimpleDataType(name+"___"+t.getQName().getLocalName(), t);
					LiteralValueUse ut = tdlFactory.eINSTANCE.createLiteralValueUse();
//					ut.setValue(t.getQName().getLocalName());
					ut.setValue(unionType.getName());
					constraint.getQuantifier().add(ut);
				}
			}
			addMapping(type.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), dataType, sourceMappingTag, targetMappingTag);

			return dataType;
		} else {
			//TODO: add constraints?
			SimpleDataType dataType = getSimpleDataTypeFor(typeName);
@@ -293,6 +360,23 @@ public class Yang2TDLTranslator extends AbstractTranslator {
				e.setExtending(superType);
				dataType.setExtension(e);
			}
			addMapping(type.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), dataType, sourceMappingTag, targetMappingTag);

			if (type instanceof StringTypeDefinition) {
				List<PatternConstraint> patternConstraints = ((StringTypeDefinition) type).getPatternConstraints();
				Constraint constraint = constrainWith(dataType, "pattern");
				if (constraint != null) {
					for (PatternConstraint c : patternConstraints) {
						LiteralValueUse ut = tdlFactory.eINSTANCE.createLiteralValueUse();
						//TODO: or getJavaPatternString?
						ut.setValue(c.getRegularExpressionString());
						constraint.getQuantifier().add(ut);
					}
				} else {
					//TODO: what if constraint is already there?
				}
			}
			
			return dataType;
		}
	}
@@ -322,9 +406,34 @@ public class Yang2TDLTranslator extends AbstractTranslator {
		for (DataSchemaNode child : c.getChildNodes()) {
			translateMember(baseName, dataType, child);
		}
		addMapping(c.toString().replaceAll(".+?argument=", "").replaceAll("}", ""), dataType, sourceMappingTag, targetMappingTag);
		return dataType;
	}
	
	//----------------------------------------------------------
	//Mappings
	
	private void addMapping(String uri, DataType dataType, String sourceMappingTag, String targetMappingTag) {
		//TODO: move mappings to a separate package
		DataElementMapping sourceMapping = addDataElementMapping(uri, dataType, sourceMappingTag);

		// TODO: make configurable?
		DataElementMapping targetMapping = addDataElementMapping("target://" + uri, dataType,
				targetMappingTag);
		targetMapping.setDataResourceMapping(drmTarget);

		if (dataType instanceof StructuredDataType) {
			//TODO: reflect source names before transformation
			for (Member m : ((StructuredDataType) dataType).getMember()) {
				addParameterMapping(sourceMapping, m, m.getName());
				addParameterMapping(targetMapping, m, m.getName());
			}
		}
	}

	
	
	
	//----------------------------------------------------------
	//TODO: clean up below
	
@@ -398,19 +507,14 @@ public class Yang2TDLTranslator extends AbstractTranslator {
            ;
	}
	
    private static YangStatementStreamSource moduleFromResources(final String resourceName) {
        try {
            return YangStatementStreamSource.create(YangTextSchemaSource.forResource(resourceName));
        } catch (final YangSyntaxErrorException | IOException e) {
            throw new IllegalStateException("Failed to find resource " + resourceName, e);
        }
    }
    private static YangStatementStreamSource moduleFromPath(String path) {
    	return moduleFromPath(Path.of(path));
    }
    private static YangStatementStreamSource moduleFromPath(Path path) {
        try {
            return YangStatementStreamSource.create(YangTextSchemaSource.forPath(path));
            // return new YangStatementSourceImpl("/example.yang", false);
            return YangStatementStreamSource.create(new FileYangTextSource(path));
            // return YangStatementStreamSource.create(YangTextSource.forResource(path));
        } catch (final YangSyntaxErrorException | IOException e) {
            throw new IllegalStateException("Failed to find resource " + path.toString(), e);
        }