From d9f05940b64a117f34b4aa0b0c67d8b4d8f14f8a Mon Sep 17 00:00:00 2001 From: Martin Ciglan Date: Tue, 17 Jan 2017 13:11:00 +0100 Subject: [PATCH] Bug 1459-1 - Re-organize mdsal-binding2-spec - new artifact mdsal-binding2-util (starts with Binding2Mapping) - new 'runtime' package for run-time support: serializer, etc.. - various replacements done based on previous changes and review comments Change-Id: I4525d2c3f706ce1e77051711c57a3ca55ecc8350 Signed-off-by: Martin Ciglan --- .../generator/api/ModuleInfoRegistry.java | 2 +- .../mdsal-binding2-generator-impl/pom.xml | 4 + .../generator/impl/AugmentToGenType.java | 10 +- .../generator/impl/GenHelperUtil.java | 30 +- .../generator/impl/ModuleToGenType.java | 4 +- .../mdsal-binding2-generator-util/pom.xml | 4 + ...torUtil.java => BindingGeneratorUtil.java} | 7 +- .../type/builder/EnumerationBuilderImpl.java | 12 +- .../mdsal-binding2-java-api-generator/pom.xml | 4 + .../generator/renderers/ClassRenderer.java | 4 +- .../YangModuleInfoTemplateRenderer.java | 8 +- .../classTemplateConstructors.scala.txt | 2 +- .../binding2/classTemplateInitBlock.scala.txt | 4 +- .../binding2/modelProviderTemplate.scala.txt | 4 +- .../binding2/yangModuleInfoTemplate.scala.txt | 6 +- .../binding2/spec/runtime/BindingCodec.java | 38 ++ .../spec/runtime/BindingDeserializer.java | 29 ++ .../spec/runtime/BindingSerializer.java | 29 ++ .../runtime/BindingStreamEventWriter.java | 493 ++++++++++++++++++ .../spec/runtime/TreeNodeSerializer.java | 30 ++ .../YangModelBindingProvider.java | 4 +- .../spec/{ => runtime}/YangModuleInfo.java | 6 +- binding2/mdsal-binding2-util/pom.xml | 64 +++ .../mdsal/binding2/util/BindingMapping.java} | 10 +- .../util/StringValueObjectFactory.java | 134 +++++ binding2/pom.xml | 1 + common/artifacts/pom.xml | 5 + 27 files changed, 891 insertions(+), 57 deletions(-) rename binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/{Binding2GeneratorUtil.java => BindingGeneratorUtil.java} (95%) create mode 100644 binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingCodec.java create mode 100644 binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingDeserializer.java create mode 100644 binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingSerializer.java create mode 100644 binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingStreamEventWriter.java create mode 100644 binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/TreeNodeSerializer.java rename binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/{ => runtime}/YangModelBindingProvider.java (84%) rename binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/{ => runtime}/YangModuleInfo.java (90%) create mode 100644 binding2/mdsal-binding2-util/pom.xml rename binding2/{mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/Binding2Mapping.java => mdsal-binding2-util/src/main/java/org/opendaylight/mdsal/binding2/util/BindingMapping.java} (96%) create mode 100644 binding2/mdsal-binding2-util/src/main/java/org/opendaylight/mdsal/binding2/util/StringValueObjectFactory.java diff --git a/binding2/mdsal-binding2-generator-api/src/main/java/org/opendaylight/mdsal/binding2/generator/api/ModuleInfoRegistry.java b/binding2/mdsal-binding2-generator-api/src/main/java/org/opendaylight/mdsal/binding2/generator/api/ModuleInfoRegistry.java index b703e33244..9eca3278a7 100644 --- a/binding2/mdsal-binding2-generator-api/src/main/java/org/opendaylight/mdsal/binding2/generator/api/ModuleInfoRegistry.java +++ b/binding2/mdsal-binding2-generator-api/src/main/java/org/opendaylight/mdsal/binding2/generator/api/ModuleInfoRegistry.java @@ -9,7 +9,7 @@ package org.opendaylight.mdsal.binding2.generator.api; import com.google.common.annotations.Beta; -import org.opendaylight.mdsal.binding2.spec.YangModuleInfo; +import org.opendaylight.mdsal.binding2.spec.runtime.YangModuleInfo; import org.opendaylight.yangtools.concepts.ObjectRegistration; /** diff --git a/binding2/mdsal-binding2-generator-impl/pom.xml b/binding2/mdsal-binding2-generator-impl/pom.xml index 74076b1660..0d689db66c 100644 --- a/binding2/mdsal-binding2-generator-impl/pom.xml +++ b/binding2/mdsal-binding2-generator-impl/pom.xml @@ -67,6 +67,10 @@ org.opendaylight.mdsal mdsal-binding2-generator-util + + org.opendaylight.mdsal + mdsal-binding2-util + com.google.code.findbugs jsr305 diff --git a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/AugmentToGenType.java b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/AugmentToGenType.java index d8f09b9cb2..d82057ddb3 100644 --- a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/AugmentToGenType.java +++ b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/AugmentToGenType.java @@ -18,11 +18,11 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import org.opendaylight.mdsal.binding2.generator.util.Binding2GeneratorUtil; -import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping; +import org.opendaylight.mdsal.binding2.generator.util.BindingGeneratorUtil; import org.opendaylight.mdsal.binding2.generator.util.ReferencedTypeImpl; import org.opendaylight.mdsal.binding2.model.api.Type; import org.opendaylight.mdsal.binding2.model.api.type.builder.GeneratedTypeBuilder; +import org.opendaylight.mdsal.binding2.util.BindingMapping; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; @@ -94,7 +94,7 @@ final class AugmentToGenType { Preconditions.checkArgument(module.getName() != null, "Module name cannot be NULL."); Preconditions.checkState(module.getAugmentations() != null, "Augmentations Set cannot be NULL."); - final String basePackageName = Binding2Mapping.getRootPackageName(module); + final String basePackageName = BindingMapping.getRootPackageName(module); final List augmentations = resolveAugmentations(module); Map resultCtx = genCtx; for (final AugmentationSchema augment : augmentations) { @@ -242,7 +242,7 @@ final class AugmentToGenType { if (!(targetSchemaNode instanceof ChoiceSchemaNode)) { String packageName = augmentPackageName; if (usesNodeParent instanceof SchemaNode) { - packageName = Binding2GeneratorUtil.packageNameForAugmentedGeneratedType(augmentPackageName, + packageName = BindingGeneratorUtil.packageNameForAugmentedGeneratedType(augmentPackageName, ((SchemaNode) usesNodeParent).getPath()); } generatedCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, @@ -355,7 +355,7 @@ final class AugmentToGenType { for (final DataSchemaNode caseNode : augmentedNodes) { if (caseNode != null) { - final String packageName = Binding2GeneratorUtil.packageNameForGeneratedType(basePackageName, + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, caseNode.getPath()); final GeneratedTypeBuilder caseTypeBuilder = GenHelperUtil.addDefaultInterfaceDefinition(packageName, caseNode, module, genCtx, schemaContext, verboseClassComments, genTypeBuilders); diff --git a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/GenHelperUtil.java b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/GenHelperUtil.java index 555bdc2634..44a38c42a1 100644 --- a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/GenHelperUtil.java +++ b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/GenHelperUtil.java @@ -19,8 +19,7 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; import org.opendaylight.mdsal.binding2.generator.impl.util.YangTextTemplate; -import org.opendaylight.mdsal.binding2.generator.util.Binding2GeneratorUtil; -import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping; +import org.opendaylight.mdsal.binding2.generator.util.BindingGeneratorUtil; import org.opendaylight.mdsal.binding2.generator.util.BindingTypes; import org.opendaylight.mdsal.binding2.generator.util.Types; import org.opendaylight.mdsal.binding2.generator.util.generated.type.builder.GeneratedTypeBuilderImpl; @@ -29,6 +28,9 @@ import org.opendaylight.mdsal.binding2.model.api.GeneratedType; import org.opendaylight.mdsal.binding2.model.api.Type; import org.opendaylight.mdsal.binding2.model.api.type.builder.GeneratedTypeBuilder; import org.opendaylight.mdsal.binding2.model.api.type.builder.GeneratedTypeBuilderBase; +import org.opendaylight.mdsal.binding2.txt.yangTemplateForModule; +import org.opendaylight.mdsal.binding2.txt.yangTemplateForNode; +import org.opendaylight.mdsal.binding2.util.BindingMapping; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; @@ -46,8 +48,6 @@ import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; -import org.opendaylight.mdsal.binding2.txt.yangTemplateForModule; -import org.opendaylight.mdsal.binding2.txt.yangTemplateForNode; /** * Helper util class used for generation of types in binding spec v2. @@ -115,8 +115,8 @@ final class GenHelperUtil { */ static GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix, final boolean verboseClassComments) { Preconditions.checkArgument(module != null, "Module reference cannot be NULL."); - final String packageName = Binding2Mapping.getRootPackageName(module); - final String moduleName = Binding2Mapping.getClassName(module.getName()) + postfix; + final String packageName = BindingMapping.getRootPackageName(module); + final String moduleName = BindingMapping.getClassName(module.getName()) + postfix; final GeneratedTypeBuilderImpl moduleBuilder = new GeneratedTypeBuilderImpl(packageName, moduleName); moduleBuilder.setDescription(createDescription(module, verboseClassComments)); @@ -171,7 +171,7 @@ final class GenHelperUtil { private static String createDescription(final Module module, final boolean verboseClassComments) { final StringBuilder sb = new StringBuilder(); - final String moduleDescription = Binding2GeneratorUtil.encodeAngleBrackets(module.getDescription()); + final String moduleDescription = BindingGeneratorUtil.encodeAngleBrackets(module.getDescription()); final String formattedDescription = YangTextTemplate.formatToParagraph(moduleDescription, 0); if (!Strings.isNullOrEmpty(formattedDescription)) { @@ -187,7 +187,7 @@ final class GenHelperUtil { sb.append(NEW_LINE); sb.append("
");
             sb.append(NEW_LINE);
-            sb.append(Binding2GeneratorUtil.encodeAngleBrackets(yangTemplateForModule.render(module).body()));
+            sb.append(BindingGeneratorUtil.encodeAngleBrackets(yangTemplateForModule.render(module).body()));
             sb.append("
"); } @@ -241,7 +241,7 @@ final class GenHelperUtil { static Map processUsesAugments(final SchemaContext schemaContext, final DataNodeContainer node, final Module module, Map genCtx, Map> genTypeBuilders, final boolean verboseClassComments) { - final String basePackageName = Binding2Mapping.getRootPackageName(module); + final String basePackageName = BindingMapping.getRootPackageName(module); for (final UsesNode usesNode : node.getUses()) { for (final AugmentationSchema augment : usesNode.getAugmentations()) { genCtx = AugmentToGenType.usesAugmentationToGenTypes(schemaContext, basePackageName, augment, module, @@ -307,7 +307,7 @@ final class GenHelperUtil { String augTypeName; if (augIdentifier != null) { - augTypeName = Binding2Mapping.getClassName(augIdentifier); + augTypeName = BindingMapping.getClassName(augIdentifier); } else { augTypeName = augGenTypeName(augmentBuilders, targetTypeRef.getName()); } @@ -495,14 +495,14 @@ final class GenHelperUtil { String genTypeName; if (prefix == null) { - genTypeName = Binding2Mapping.getClassName(schemaNodeName); + genTypeName = BindingMapping.getClassName(schemaNodeName); } else { - genTypeName = prefix + Binding2Mapping.getClassName(schemaNodeName); + genTypeName = prefix + BindingMapping.getClassName(schemaNodeName); } final GeneratedTypeBuilderImpl newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); final Module module = SchemaContextUtil.findParentModule(schemaContext, schemaNode); - qNameConstant(newType, Binding2Mapping.QNAME_STATIC_FIELD_NAME, schemaNode.getQName()); + qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, schemaNode.getQName()); newType.addComment(schemaNode.getDescription()); newType.setDescription(createDescription(schemaNode, newType.getFullyQualifiedName(), schemaContext, verboseClassComments)); newType.setReference(schemaNode.getReference()); @@ -532,7 +532,7 @@ final class GenHelperUtil { private static String createDescription(final SchemaNode schemaNode, final String fullyQualifiedName, final SchemaContext schemaContext, final boolean verboseClassComments) { final StringBuilder sb = new StringBuilder(); - final String nodeDescription = Binding2GeneratorUtil.encodeAngleBrackets(schemaNode.getDescription()); + final String nodeDescription = BindingGeneratorUtil.encodeAngleBrackets(schemaNode.getDescription()); final String formattedDescription = YangTextTemplate.formatToParagraph(nodeDescription, 0); if (!Strings.isNullOrEmpty(formattedDescription)) { @@ -558,7 +558,7 @@ final class GenHelperUtil { sb.append(NEW_LINE); sb.append("
");
             sb.append(NEW_LINE);
-            sb.append(Binding2GeneratorUtil.encodeAngleBrackets(yangTemplateForNode.render(schemaNode).body()));
+            sb.append(BindingGeneratorUtil.encodeAngleBrackets(yangTemplateForNode.render(schemaNode).body()));
             sb.append("
"); sb.append(NEW_LINE); sb.append("The schema path to identify an instance is"); diff --git a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/ModuleToGenType.java b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/ModuleToGenType.java index 60c7e317f2..1fb386603a 100644 --- a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/ModuleToGenType.java +++ b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding2/generator/impl/ModuleToGenType.java @@ -14,10 +14,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import org.opendaylight.mdsal.binding2.generator.spi.TypeProvider; -import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping; import org.opendaylight.mdsal.binding2.generator.yang.types.TypeProviderImpl; import org.opendaylight.mdsal.binding2.model.api.Type; import org.opendaylight.mdsal.binding2.model.api.type.builder.GeneratedTypeBuilder; +import org.opendaylight.mdsal.binding2.util.BindingMapping; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; @@ -42,7 +42,7 @@ final class ModuleToGenType { if (!module.getChildNodes().isEmpty()) { final GeneratedTypeBuilder moduleType = GenHelperUtil.moduleToDataType(module, genCtx, verboseClassComments); genCtx.get(module).addModuleNode(moduleType); - final String basePackageName = Binding2Mapping.getRootPackageName(module); + final String basePackageName = BindingMapping.getRootPackageName(module); GenHelperUtil.resolveDataSchemaNodes(module, basePackageName, moduleType, moduleType, module .getChildNodes()); } diff --git a/binding2/mdsal-binding2-generator-util/pom.xml b/binding2/mdsal-binding2-generator-util/pom.xml index 1c5fba704b..e90d1119f2 100644 --- a/binding2/mdsal-binding2-generator-util/pom.xml +++ b/binding2/mdsal-binding2-generator-util/pom.xml @@ -54,6 +54,10 @@ org.opendaylight.mdsal mdsal-binding2-spec
+ + org.opendaylight.mdsal + mdsal-binding2-util + org.opendaylight.yangtools yang-parser-impl diff --git a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/Binding2GeneratorUtil.java b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/BindingGeneratorUtil.java similarity index 95% rename from binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/Binding2GeneratorUtil.java rename to binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/BindingGeneratorUtil.java index 19062cae69..6cbebecc17 100644 --- a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/Binding2GeneratorUtil.java +++ b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/BindingGeneratorUtil.java @@ -12,6 +12,7 @@ import com.google.common.annotations.Beta; import com.google.common.base.CharMatcher; import com.google.common.collect.Iterables; import java.util.Iterator; +import org.opendaylight.mdsal.binding2.util.BindingMapping; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.SchemaPath; @@ -21,12 +22,12 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; * class names, attribute names and/or valid JavaDoc comments. */ @Beta -public final class Binding2GeneratorUtil { +public final class BindingGeneratorUtil { private static final CharMatcher GT_MATCHER = CharMatcher.is('>'); private static final CharMatcher LT_MATCHER = CharMatcher.is('<'); - private Binding2GeneratorUtil() { + private BindingGeneratorUtil() { throw new UnsupportedOperationException("Utility class"); } @@ -102,7 +103,7 @@ public final class Binding2GeneratorUtil { //FIXME: colon or dash in identifier? builder.append(nodeLocalName); } - return Binding2Mapping.normalizePackageName(builder.toString()); + return BindingMapping.normalizePackageName(builder.toString()); } /** diff --git a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/generated/type/builder/EnumerationBuilderImpl.java b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/generated/type/builder/EnumerationBuilderImpl.java index 0f04ed9bd6..f27785c3e9 100644 --- a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/generated/type/builder/EnumerationBuilderImpl.java +++ b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/generated/type/builder/EnumerationBuilderImpl.java @@ -17,7 +17,6 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.mdsal.binding2.generator.util.AbstractBaseType; -import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping; import org.opendaylight.mdsal.binding2.model.api.AnnotationType; import org.opendaylight.mdsal.binding2.model.api.Constant; import org.opendaylight.mdsal.binding2.model.api.Enumeration; @@ -28,6 +27,7 @@ import org.opendaylight.mdsal.binding2.model.api.MethodSignature; import org.opendaylight.mdsal.binding2.model.api.Type; import org.opendaylight.mdsal.binding2.model.api.type.builder.AnnotationTypeBuilder; import org.opendaylight.mdsal.binding2.model.api.type.builder.EnumBuilder; +import org.opendaylight.mdsal.binding2.util.BindingMapping; import org.opendaylight.yangtools.util.LazyCollections; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Status; @@ -99,7 +99,7 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil builder.append(name); builder.append(", values="); builder.append(values); - builder.append("]"); + builder.append(']'); return builder.toString(); } @@ -125,7 +125,7 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil final String reference, final Status status) { this.name = name; - this.mappedName = Binding2Mapping.getClassName(name); + this.mappedName = BindingMapping.getClassName(name); this.value = value; this.description = description; this.reference = reference; @@ -202,7 +202,7 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil builder.append(getMappedName()); builder.append(", value="); builder.append(value); - builder.append("]"); + builder.append(']'); return builder.toString(); } } @@ -257,7 +257,7 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil public String toFormattedString() { StringBuilder builder = new StringBuilder(); builder.append("public enum"); - builder.append(" "); + builder.append(' '); builder.append(getName()); builder.append(" {"); builder.append("\n"); @@ -265,7 +265,7 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil int i = 0; for (final Enumeration.Pair valPair : values) { builder.append("\t"); - builder.append(" "); + builder.append(' '); builder.append(valPair.getMappedName()); builder.append(" ("); builder.append(valPair.getValue()); diff --git a/binding2/mdsal-binding2-java-api-generator/pom.xml b/binding2/mdsal-binding2-java-api-generator/pom.xml index 9f6dc691ae..c58023e865 100644 --- a/binding2/mdsal-binding2-java-api-generator/pom.xml +++ b/binding2/mdsal-binding2-java-api-generator/pom.xml @@ -51,6 +51,10 @@ org.opendaylight.mdsal mdsal-binding2-generator-util + + org.opendaylight.mdsal + mdsal-binding2-util + junit junit diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/ClassRenderer.java b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/ClassRenderer.java index c459c12b6d..b7eb058187 100644 --- a/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/ClassRenderer.java +++ b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/ClassRenderer.java @@ -8,10 +8,10 @@ package org.opendaylight.mdsal.binding2.java.api.generator.renderers; -import static org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.MEMBER_PATTERN_LIST; -import static org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.PATTERN_CONSTANT_NAME; import static org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.fieldName; import static org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.setterMethod; +import static org.opendaylight.mdsal.binding2.util.BindingMapping.MEMBER_PATTERN_LIST; +import static org.opendaylight.mdsal.binding2.util.BindingMapping.PATTERN_CONSTANT_NAME; import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/YangModuleInfoTemplateRenderer.java b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/YangModuleInfoTemplateRenderer.java index d297f45dc2..2b79bc6835 100644 --- a/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/YangModuleInfoTemplateRenderer.java +++ b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/YangModuleInfoTemplateRenderer.java @@ -8,8 +8,8 @@ package org.opendaylight.mdsal.binding2.java.api.generator.renderers; -import static org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.MODEL_BINDING_PROVIDER_CLASS_NAME; -import static org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.getRootPackageName; +import static org.opendaylight.mdsal.binding2.util.BindingMapping.MODEL_BINDING_PROVIDER_CLASS_NAME; +import static org.opendaylight.mdsal.binding2.util.BindingMapping.getRootPackageName; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; @@ -26,8 +26,8 @@ import org.opendaylight.mdsal.binding2.generator.util.Types; import org.opendaylight.mdsal.binding2.model.api.ParameterizedType; import org.opendaylight.mdsal.binding2.model.api.Type; import org.opendaylight.mdsal.binding2.model.api.WildcardType; -import org.opendaylight.mdsal.binding2.spec.YangModelBindingProvider; -import org.opendaylight.mdsal.binding2.spec.YangModuleInfo; +import org.opendaylight.mdsal.binding2.spec.runtime.YangModelBindingProvider; +import org.opendaylight.mdsal.binding2.spec.runtime.YangModuleInfo; import org.opendaylight.mdsal.binding2.txt.modelProviderTemplate; import org.opendaylight.mdsal.binding2.txt.yangModuleInfoTemplate; import org.opendaylight.yangtools.yang.model.api.Module; diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/classTemplateConstructors.scala.txt b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/classTemplateConstructors.scala.txt index 6d4918d0c3..6d5d7e3308 100644 --- a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/classTemplateConstructors.scala.txt +++ b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/classTemplateConstructors.scala.txt @@ -6,11 +6,11 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html *@ -@import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.PATTERN_CONSTANT_NAME @import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.asArguments @import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.fieldName @import org.opendaylight.mdsal.binding2.model.api.GeneratedTransferObject @import org.opendaylight.mdsal.binding2.model.api.GeneratedProperty +@import org.opendaylight.mdsal.binding2.util.BindingMapping.PATTERN_CONSTANT_NAME @(genTo: GeneratedTransferObject, allProperties: List[GeneratedProperty], properties: List[GeneratedProperty], parentProperties: List[GeneratedProperty], importedNames: Map[String, String], argumentsDeclaration: String, diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/classTemplateInitBlock.scala.txt b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/classTemplateInitBlock.scala.txt index de003a845a..37636245d8 100644 --- a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/classTemplateInitBlock.scala.txt +++ b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/classTemplateInitBlock.scala.txt @@ -6,8 +6,8 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html *@ -@import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.PATTERN_CONSTANT_NAME -@import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.MEMBER_PATTERN_LIST +@import org.opendaylight.mdsal.binding2.util.BindingMapping.MEMBER_PATTERN_LIST +@import org.opendaylight.mdsal.binding2.util.BindingMapping.PATTERN_CONSTANT_NAME @(patterName: String) static { diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/modelProviderTemplate.scala.txt b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/modelProviderTemplate.scala.txt index aac79e4972..85ba2d7acd 100644 --- a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/modelProviderTemplate.scala.txt +++ b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/modelProviderTemplate.scala.txt @@ -6,8 +6,8 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html *@ -@import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.MODULE_INFO_CLASS_NAME -@import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.MODEL_BINDING_PROVIDER_CLASS_NAME +@import org.opendaylight.mdsal.binding2.util.BindingMapping.MODEL_BINDING_PROVIDER_CLASS_NAME +@import org.opendaylight.mdsal.binding2.util.BindingMapping.MODULE_INFO_CLASS_NAME @(packageName: String, yangModelBindingProviderName: String, yangModuleInfoName: String) package @{packageName}; diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/yangModuleInfoTemplate.scala.txt b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/yangModuleInfoTemplate.scala.txt index e7efcca0d7..550bf489b8 100644 --- a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/yangModuleInfoTemplate.scala.txt +++ b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/yangModuleInfoTemplate.scala.txt @@ -6,12 +6,12 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html *@ -@import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.getClassName -@import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.getRootPackageName -@import org.opendaylight.mdsal.binding2.generator.util.Binding2Mapping.MODULE_INFO_CLASS_NAME @import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.getFormattedRevision @import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.getSourcePath @import org.opendaylight.mdsal.binding2.java.api.generator.renderers.YangModuleInfoTemplateRenderer.getSortedQName +@import org.opendaylight.mdsal.binding2.util.BindingMapping.getClassName +@import org.opendaylight.mdsal.binding2.util.BindingMapping.getRootPackageName +@import org.opendaylight.mdsal.binding2.util.BindingMapping.MODULE_INFO_CLASS_NAME @import org.opendaylight.yangtools.yang.model.api.Module @import org.opendaylight.yangtools.yang.model.api.SchemaContext diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingCodec.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingCodec.java new file mode 100644 index 0000000000..a834cfb2b5 --- /dev/null +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingCodec.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.mdsal.binding2.spec.runtime; + +import com.google.common.annotations.Beta; +import org.opendaylight.yangtools.concepts.Codec; + +/** + * Base interface for Binding2 encoding/decoding mechanism implementation + */ +@Beta +public interface BindingCodec extends BindingSerializer, BindingDeserializer, Codec { + + /** + * Produces an object based on input. + * + * @param input Input object + * @return Product derived from input + */ + @Override + P serialize(I input); + + /** + * Produces an object based on input. + * + * @param input Input object + * @return Product derived from input + */ + @Override + I deserialize(P input); + +} \ No newline at end of file diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingDeserializer.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingDeserializer.java new file mode 100644 index 0000000000..8fead6f78e --- /dev/null +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingDeserializer.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.mdsal.binding2.spec.runtime; + +import com.google.common.annotations.Beta; + +/** + * The concept of a deserializer in Binding part, which produces an object from some input. + * + * @param

Product type + * @param Input type + */ +@Beta +public interface BindingDeserializer { + + /** + * Produces an object based on input. + * + * @param input Input object + * @return Product derived from input + */ + P deserialize(I input); +} diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingSerializer.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingSerializer.java new file mode 100644 index 0000000000..b9c7579bf0 --- /dev/null +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingSerializer.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.mdsal.binding2.spec.runtime; + +import com.google.common.annotations.Beta; + +/** + * The concept of a serializer in Binding part, which produces an object from some input. + * + * @param

Product type + * @param Input type + */ +@Beta +public interface BindingSerializer { + + /** + * Produces an object based on input. + * + * @param input Input object + * @return Product derived from input + */ + P serialize(I input); +} \ No newline at end of file diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingStreamEventWriter.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingStreamEventWriter.java new file mode 100644 index 0000000000..7d45475bb0 --- /dev/null +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/BindingStreamEventWriter.java @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.mdsal.binding2.spec.runtime; + +import com.google.common.annotations.Beta; +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; +import org.opendaylight.mdsal.binding2.spec.Augmentation; +import org.opendaylight.mdsal.binding2.spec.IdentifiableItem; +import org.opendaylight.mdsal.binding2.spec.Item; +import org.opendaylight.mdsal.binding2.spec.TreeNode; + +/** + * Event Stream Writer for Binding version 2 Representation + * + * + *

Emitting Event Stream

+ * + *
    + *
  • container - Container node representation, start event is + * emitted using {@link #startContainerNode(Class, int)} and node end event is + * emitted using {@link #endNode()}. Container node is implementing + * {@link TreeNode} interface. + * + *
  • list - YANG list statement has two representations in event + * stream - un-keyed list and map. Un-keyed list is YANG list which didn't + * specify key. + * + *
      + *
    • Map - Map start event is emitted using + * {@link #startMapNode(IdentifiableItem, int)} and is ended using {@link #endNode()}. Each map + * entry start is emitted using {@link #startMapEntryNode(IdentifiableItem, int)} with Map of keys + * and finished using {@link #endNode()}.
    • + * + *
    • UnkeyedList - Un-keyed list represents list without keys, + * un-keyed list start is emitted using {@link #startUnkeyedList(Class, int)}, list + * end is emitted using {@link #endNode()}. Each list item is emitted using + * {@link #startUnkeyedListItem(int)} and ended using {@link #endNode()}.
    • + *
  • + * + *
  • leaf - Leaf node event is emitted using + * {@link #startleafNode(String, Object)}. {@link #endNode()} MUST NOT be emitted for + * leaf node.
  • + * + *
  • leaf-list - Leaf list start is emitted using + * {@link #startLeafSet(String, int)}. Leaf list end is emitted using + * {@link #endNode()}. Leaf list entries are emitted using + * {@link #startleafSetEntryNode(Object)}. + * + *
  • anyxml - Anyxml node event is emitted using + * {@link #startAnyxmlNode(String, Object)}. {@link #endNode()} MUST NOT be emitted + * for anyxml node.
  • + * + *
  • anydata - Anydata node event is emitted using + * {@link #startAnydataNode(String, Object)}. {@link #endNode()} MUST NOT be emitted + * for anydata node.
  • + * + *
  • choice Choice node event is emitted by + * {@link #startChoiceNode(Item, int)} event and must be immediately followed by + * {@link #startCase(Class, int)} event. Choice node is finished by emitting an + * {@link #endNode()} event.
  • + * + *
  • + * case - Case node may be emitted only inside choice node by + * invoking {@link #startCase(Class, int)}. Case node is finished be emitting an + * {@link #endNode()} event.
  • + * + *
  • + * augment - Represents augmentation, augmentation node is started + * by invoking {@link #startAugmentationNode(Class)} and + * finished by invoking {@link #endNode()}.
  • + * + *
+ * + *

Implementation notes

This interface is not intended to be + * implemented by users of generated Binding2 DTOs but to be used by utilities, + * which needs to emit NormalizedNode model from Binding2 DTOs. + *

+ * This interface is intended as API definition of facade for real Event / + * Stream Writer, without explicitly requiring stream writer and related + * interfaces to be imported by all generated Binding2 DTOs. + *

+ * Existence of this interface in runtime Java Binding2 package is required to + * support runtime generation of users of this interface in OSGI and OSGI-like + * environment, since this package is only package which is imported by all + * generated Binding2 DTOs and wired in OSGI. + * + * + */ +@Beta +public interface BindingStreamEventWriter extends Closeable, Flushable { + + /** + * Methods in this interface allow users to hint the underlying + * implementation about the sizing of container-like constructors + * (leafLists, containers, etc.). These hints may be taken into account by a + * particular implementation to improve performance, but clients are not + * required to provide hints. This constant should be used by clients who + * either do not have the sizing information, or do not wish to divulge it + * (for whatever reasons). Implementations are free to ignore these hints + * completely, but if they do use them, they are expected to be resilient in + * face of missing and mismatched hints, which is to say the user can + * specify startLeafSet(..., 1) and then call leafNode() 15 times. + *

+ * The acceptable hint values are non-negative integers and this constant, + * all other values will result, based on implementation preference, in the + * hint being completely ignored or IllegalArgumentException being thrown. + */ + int UNKNOWN_SIZE = -1; + + /** + * + * Emits a leaf node event with supplied value. + * + * @param localName + * name of node as defined in schema, namespace and revision are + * derived from parent node. + * @param value + * Value of leaf node. + * @throws IllegalArgumentException + * If emitted leaf node has invalid value in current context or + * was emitted multiple times. + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startleafNode(String localName, Object value) throws IOException; + + /** + * + * Emits a start of leaf set (leaf-list). + *

+ * Emits start of leaf set, during writing leaf set event, only + * {@link #startleafSetEntryNode(Object)} calls are valid. Leaf set event is + * finished by calling {@link #endNode()}. + * + * @param localName + * name of node as defined in schema, namespace and revision are + * derived from parent node. + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalArgumentException + * If emitted leaf node is invalid in current context or was + * emitted multiple times. + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startLeafSet(String localName, int childSizeHint) throws IOException; + + /** + * + * Emits a start of leaf set (leaf-list). + *

+ * Emits start of leaf set, during writing leaf set event, only + * {@link #startleafSetEntryNode(Object)} calls are valid. Leaf set event is + * finished by calling {@link #endNode()}. + * + * @param localName + * name of node as defined in schema, namespace and revision are + * derived from parent node. + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalArgumentException + * If emitted leaf node is invalid in current context or was + * emitted multiple times. + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startOrderedLeafSet(String localName, int childSizeHint) throws IOException; + + /** + * Emits a leaf set entry node + * + * @param value + * Value of leaf set entry node. + * @throws IllegalArgumentException + * If emitted leaf node has invalid value. + * @throws IllegalStateException + * If node was emitted outside leaf set node. + * @throws IOException if an underlying IO error occurs + */ + void startleafSetEntryNode(Object value) throws IOException; + + /** + * + * Emits start of new container. + * + *

+ * End of container event is emitted by invoking {@link #endNode()}. + * + *

+ * Valid sub-events are: + *

    + *
  • {@link #startleafNode(String, Object)}
  • + *
  • {@link #startContainerNode(Class, int)}
  • + *
  • {@link #startChoiceNode(Item, int)}
  • + *
  • {@link #startLeafSet(String, int)}
  • + *
  • {@link #startMapNode(IdentifiableItem, int)}
  • + *
  • {@link #startUnkeyedList(Class, int)}
  • + *
  • {@link #startAugmentationNode(Class)}
  • + *
+ * + * @param container + * name of node as defined in schema, namespace and revision are + * derived from parent node. + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalArgumentException + * If emitted node is invalid in current context or was emitted + * multiple times. + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startContainerNode(Class container, int childSizeHint) throws IOException; + + /** + * + * Emits start of unkeyed list node event. + * + *

+ * End of unkeyed list event is emitted by invoking {@link #endNode()}. + * Valid sub-event is only {@link #startUnkeyedListItem(int)}. All other + * methods will throw {@link IllegalArgumentException}. + * + * @param localName + * name of node as defined in schema, namespace and revision are + * derived from parent node. + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalArgumentException + * If emitted node is invalid in current context or was emitted + * multiple times. + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startUnkeyedList(Class localName, int childSizeHint) throws IOException; + + /** + * Emits start of new unkeyed list item. + * + *

+ * Un-keyed list item event is finished by invoking {@link #endNode()}. + *

+ * Valid sub-events are: + * + *

    + *
  • {@link #startleafNode(String, Object)}
  • + *
  • {@link #startContainerNode(Class, int)}
  • + *
  • {@link #startChoiceNode(Item, int)}
  • + *
  • {@link #startLeafSet(String, int)}
  • + *
  • {@link #startMapNode(IdentifiableItem, int)}
  • + *
  • {@link #startUnkeyedList(Class, int)}
  • + *
  • {@link #startAugmentationNode(Class)}
  • + *
+ * + * + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalStateException + * If node was emitted outside unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startUnkeyedListItem(int childSizeHint) throws IOException; + + /** + * + * Emits start of unordered map node event. + * + *

+ * End of map node event is emitted by invoking {@link #endNode()}. Valid + * subevents is only {@link #startMapEntryNode(IdentifiableItem, int)}. All other methods will + * throw {@link IllegalArgumentException}. + * + * @param mapEntryType + * Class of list item, which has defined key. + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalArgumentException + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startMapNode(IdentifiableItem mapEntryType, int childSizeHint) + throws IOException; + + /** + * + * Emits start of ordered map node event. + * + *

+ * End of map node event is emitted by invoking {@link #endNode()}. Valid + * sub-event is only {@link #startMapEntryNode(IdentifiableItem, int)}. All other methods will + * throw {@link IllegalArgumentException}. + * + * @param mapEntryType + * Class of list item, which has defined key. + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalArgumentException + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startOrderedMapNode(IdentifiableItem mapEntryType, int childSizeHint) + throws IOException; + + /** + * + * Emits start of map entry. + * + *

+ * End of map entry event is emitted by invoking {@link #endNode()}. + * + *

+ * Valid sub-events are: + *

    + *
  • {@link #startleafNode(String, Object)}
  • + *
  • {@link #startContainerNode(Class, int)}
  • + *
  • {@link #startChoiceNode(Item, int)}
  • + *
  • {@link #startLeafSet(String, int)}
  • + *
  • {@link #startMapNode(IdentifiableItem, int)}
  • + *
  • {@link #startUnkeyedList(Class, int)}
  • + *
  • {@link #startAugmentationNode(Class)}
  • + *
+ * + * @param keyValues + * Key of map entry node + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalArgumentException + * If key contains incorrect value. + * @throws IllegalStateException + * If node was emitted outside map entry node. + * @throws IOException if an underlying IO error occurs + */ + void startMapEntryNode(IdentifiableItem keyValues, int childSizeHint) + throws IOException; + + /** + * Emits start of choice node. + * + *

+ * Valid sub-event is {@link #startCase(Class, int)}, which selects case + * which should be written. + * + * @param choice + * Choice class. + * @param childSizeHint + * Non-negative count of expected direct child nodes or + * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint + * and should not fail writing of child events, if there are more + * events than count. + * @throws IllegalArgumentException + * @throws IllegalStateException + * If node was emitted inside map, choice, + * unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startChoiceNode(Item choice, int childSizeHint) throws IOException; + + /** + * + * Starts a case node. + * + *

+ * Valid sub-events are: + *

    + *
  • {@link #startleafNode(String, Object)}
  • + *
  • {@link #startContainerNode(Class, int)}
  • + *
  • {@link #startChoiceNode(Item, int)}
  • + *
  • {@link #startLeafSet(String, int)}
  • + *
  • {@link #startMapNode(IdentifiableItem, int)}
  • + *
  • {@link #startUnkeyedList(Class, int)}
  • + *
  • {@link #startAugmentationNode(Class)}
  • + *
+ * + * @param caze Case class + * @throws IllegalArgumentException + * @throws IOException if an underlying IO error occurs + */ + void startCase(Class caze, int childSizeHint) throws IOException; + + /** + * Emits start of augmentation node. + * + *

+ * End of augmentation event is emitted by invoking {@link #endNode()}. + * + *

+ * Valid sub-events are: + * + *

    + *
  • {@link #startleafNode(String, Object)}
  • + *
  • {@link #startContainerNode(Class, int)}
  • + *
  • {@link #startChoiceNode(Item, int)}
  • + *
  • {@link #startLeafSet(String, int)}
  • + *
  • {@link #startMapNode(IdentifiableItem, int)}
  • + *
  • {@link #startUnkeyedList(Class, int)}
  • + *
+ * + *

+ * Note this is only method, which does not require childSizeHint, since + * maximum value is always size of possibleChildren. + * + * @param augmentationType augmentation class + * @throws IllegalArgumentException + * If augmentation is invalid in current context. + * @throws IOException if an underlying IO error occurs + */ + void startAugmentationNode(Class> augmentationType) throws IOException; + + /** + * Emits anyxml node event. + * + * @param name + * @param value + * @throws IllegalArgumentException + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startAnyxmlNode(String name, Object value) throws IOException; + + /** + * Emits anydata node event. + * + * @param name + * @param value + * @throws IllegalStateException + * If node was emitted inside map, + * choice unkeyed list node. + * @throws IOException if an underlying IO error occurs + */ + void startAnydataNode(String name, Object value) throws IOException; + + /** + * Emits end event for node. + * + * @throws IllegalStateException If there is no open node. + * @throws IOException if an underlying IO error occurs + */ + void endNode() throws IOException; + + @Override + void flush() throws IOException; + + @Override + void close() throws IOException; +} + diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/TreeNodeSerializer.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/TreeNodeSerializer.java new file mode 100644 index 0000000000..3ca856c1ea --- /dev/null +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/TreeNodeSerializer.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.mdsal.binding2.spec.runtime; + +import com.google.common.annotations.Beta; +import java.io.IOException; +import org.opendaylight.mdsal.binding2.spec.TreeNode; + +/* + * A serializer which writes TreeNode to supplied stream event writer. + */ +@Beta +public interface TreeNodeSerializer { + + /** + * Writes stream events representing object to supplied stream + * + * @param obj + * Source of stream events + * @param stream + * Stream to which events should be written. + */ + void serialize(TreeNode obj, BindingStreamEventWriter stream) throws IOException; +} \ No newline at end of file diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/YangModelBindingProvider.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/YangModelBindingProvider.java similarity index 84% rename from binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/YangModelBindingProvider.java rename to binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/YangModelBindingProvider.java index dae067a908..0bdffdc619 100644 --- a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/YangModelBindingProvider.java +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/YangModelBindingProvider.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.mdsal.binding2.spec; +package org.opendaylight.mdsal.binding2.spec.runtime; import java.util.ServiceLoader; diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/YangModuleInfo.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/YangModuleInfo.java similarity index 90% rename from binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/YangModuleInfo.java rename to binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/YangModuleInfo.java index b76d3f1bc7..a7482219f4 100644 --- a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/YangModuleInfo.java +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding2/spec/runtime/YangModuleInfo.java @@ -1,17 +1,15 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.mdsal.binding2.spec; +package org.opendaylight.mdsal.binding2.spec.runtime; import com.google.common.annotations.Beta; import com.google.common.base.Optional; -import java.io.IOException; -import java.io.InputStream; import java.util.Set; import org.opendaylight.yangtools.concepts.SemVer; import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation; diff --git a/binding2/mdsal-binding2-util/pom.xml b/binding2/mdsal-binding2-util/pom.xml new file mode 100644 index 0000000000..d58e80334a --- /dev/null +++ b/binding2/mdsal-binding2-util/pom.xml @@ -0,0 +1,64 @@ + + + + + + + org.opendaylight.odlparent + bundle-parent + 1.8.0-SNAPSHOT + + + + 4.0.0 + org.opendaylight.mdsal + mdsal-binding2-util + 0.10.0-SNAPSHOT + bundle + ${project.artifactId} + ${project.artifactId} + + + + + org.opendaylight.yangtools + yangtools-artifacts + 1.1.0-SNAPSHOT + pom + import + + + + + + + org.opendaylight.yangtools + yang-model-api + + + + + ${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/ + + + + opendaylight-site + ${nexus.site.url}/${project.artifactId}/ + + + + \ No newline at end of file diff --git a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/Binding2Mapping.java b/binding2/mdsal-binding2-util/src/main/java/org/opendaylight/mdsal/binding2/util/BindingMapping.java similarity index 96% rename from binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/Binding2Mapping.java rename to binding2/mdsal-binding2-util/src/main/java/org/opendaylight/mdsal/binding2/util/BindingMapping.java index 696ca15e9f..6e6b78afbe 100644 --- a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding2/generator/util/Binding2Mapping.java +++ b/binding2/mdsal-binding2-util/src/main/java/org/opendaylight/mdsal/binding2/util/BindingMapping.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.mdsal.binding2.generator.util; +package org.opendaylight.mdsal.binding2.util; import com.google.common.annotations.Beta; import com.google.common.base.CharMatcher; @@ -26,7 +26,7 @@ import org.opendaylight.yangtools.yang.model.api.Module; * Standard Util class that provides generated Java related functionality */ @Beta -public final class Binding2Mapping { +public final class BindingMapping { public static final Set JAVA_RESERVED_WORDS = ImmutableSet.of("abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "double", "do", "else", "enum", @@ -62,7 +62,7 @@ public final class Binding2Mapping { } }; - private Binding2Mapping() { + private BindingMapping() { throw new UnsupportedOperationException("Utility class"); } @@ -131,7 +131,7 @@ public final class Binding2Mapping { } //FIXME: don't use underscore in v2 - if (Character.isDigit(p.charAt(0)) || Binding2Mapping.JAVA_RESERVED_WORDS.contains(p)) { + if (Character.isDigit(p.charAt(0)) || BindingMapping.JAVA_RESERVED_WORDS.contains(p)) { builder.append('_'); } builder.append(p); diff --git a/binding2/mdsal-binding2-util/src/main/java/org/opendaylight/mdsal/binding2/util/StringValueObjectFactory.java b/binding2/mdsal-binding2-util/src/main/java/org/opendaylight/mdsal/binding2/util/StringValueObjectFactory.java new file mode 100644 index 0000000000..69bde834e4 --- /dev/null +++ b/binding2/mdsal-binding2-util/src/main/java/org/opendaylight/mdsal/binding2/util/StringValueObjectFactory.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.mdsal.binding2.util; + +import com.google.common.annotations.Beta; +import com.google.common.base.Preconditions; +import com.google.common.base.Throwables; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility class for instantiating value-type generated objects with String being the base type. Unlike the normal + * constructor, instances of this class bypass string validation. + * + * THE USE OF THIS CLASS IS DANGEROUS AND SHOULD ONLY BE USED TO IMPLEMENT WELL-AUDITED AND CORRECT UTILITY METHODS + * SHIPPED WITH MODELS TO PROVIDE INSTANTIATION FROM TYPES DIFFERENT THAN STRING. + * + * APPLICATION CODE MUST NOT USE THIS CLASS DIRECTLY. VIOLATING THIS CONSTRAINT HAS SECURITY AND CORRECTNESS + * IMPLICATIONS ON EVERY USER INTERACTING WITH THE RESULTING OBJECTS. + * + * @param Resulting object type + */ +@Beta +public final class StringValueObjectFactory { + + private static final MethodType CONSTRUCTOR_METHOD_TYPE = MethodType.methodType(Object.class, Object.class); + private static final MethodType SETTER_METHOD_TYPE = MethodType.methodType(void.class, Object.class, String.class); + private static final Logger LOG = LoggerFactory.getLogger(StringValueObjectFactory.class); + private static final Lookup LOOKUP = MethodHandles.lookup(); + + private final MethodHandle constructor; + private final MethodHandle setter; + private final T template; + + private StringValueObjectFactory(final T template, final MethodHandle constructor, final MethodHandle setter) { + this.template = Preconditions.checkNotNull(template); + this.constructor = constructor.bindTo(template); + this.setter = Preconditions.checkNotNull(setter); + } + + public static StringValueObjectFactory create(final Class clazz, final String templateString) { + final Constructor stringConstructor; + try { + stringConstructor = clazz.getConstructor(String.class); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(String.format("%s does not have a String constructor", clazz), e); + } + + final T template; + try { + template = stringConstructor.newInstance(templateString); + } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { + throw new IllegalArgumentException(String.format("Failed to instantiate template %s for '%s'", clazz, + templateString), e); + } + + final Constructor copyConstructor; + try { + copyConstructor = clazz.getConstructor(clazz); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(String.format("%s does not have a copy constructor", clazz), e); + } + + final Field f; + try { + f = clazz.getDeclaredField("_value"); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException(String.format("%s does not have required internal field", clazz), e); + } + f.setAccessible(true); + + final StringValueObjectFactory ret; + try { + ret = new StringValueObjectFactory<>(template, + LOOKUP.unreflectConstructor(copyConstructor).asType(CONSTRUCTOR_METHOD_TYPE), + LOOKUP.unreflectSetter(f).asType(SETTER_METHOD_TYPE)); + } catch (IllegalAccessException e) { + throw new IllegalStateException("Failed to instantiate method handles", e); + } + + // Let us be very defensive and scream loudly if the invocation does not come from the same package. This + // is far from perfect, but better than nothing. + final Throwable t = new Throwable("Invocation stack"); + t.fillInStackTrace(); + if (matchesPackage(clazz.getPackage().getName(), t.getStackTrace())) { + LOG.info("Instantiated factory for {}", clazz); + } else { + LOG.warn("Instantiated factory for {} outside its package", clazz, t); + } + + return ret; + } + + private static boolean matchesPackage(final String pkg, final StackTraceElement[] stackTrace) { + for (StackTraceElement e : stackTrace) { + final String sp = e.getClassName(); + if (sp.startsWith(pkg) && sp.lastIndexOf('.') == pkg.length()) { + return true; + } + } + + return false; + } + + public T newInstance(final String string) { + Preconditions.checkNotNull(string, "Argument may not be null"); + + try { + final T ret = (T) constructor.invokeExact(); + setter.invokeExact(ret, string); + LOG.trace("Instantiated new object {} value {}", ret.getClass(), string); + return ret; + } catch (Throwable e) { + throw Throwables.propagate(e); + } + } + + public T getTemplate() { + return template; + } +} diff --git a/binding2/pom.xml b/binding2/pom.xml index 3fe009d385..541d2e6d6f 100644 --- a/binding2/pom.xml +++ b/binding2/pom.xml @@ -32,6 +32,7 @@ mdsal-binding2-generator-impl mdsal-binding2-java-api-generator mdsal-binding2-generator-util + mdsal-binding2-util