From e39258373ef182875663387894f6083d8113ef60 Mon Sep 17 00:00:00 2001 From: Martin Vitez Date: Thu, 13 Jun 2013 17:25:18 +0200 Subject: [PATCH] Added support for source code generation from identity statement, grouping statement and identityref type statement. Introduce new BaseIdentity class as base for all classes generated from identity statements. Introduce new WildcardType interface to add possibility to generate wildcard java type parameters in generated code. Updated tests. Change-Id: I99de20dc4268be43ec9966461aeb75521fe5dd6c Signed-off-by: Martin Vitez --- .../generator/impl/BindingGeneratorImpl.java | 85 ++ .../binding/yang/types/TypeProviderImpl.java | 30 +- .../binding/generator/util/Types.java | 39 +- .../type/builder/GeneratedTOBuilderImpl.java | 82 +- .../api/generator/ClassCodeGenerator.java | 7 +- .../sal/java/api/generator/Constants.java | 5 +- .../sal/java/api/generator/GeneratorUtil.java | 1330 +++++++++-------- .../yang/abstract-topology@2013-02-08.yang | 32 +- .../api/GeneratedTransferIdentityObject.java | 6 + .../sal/binding/model/api/WildcardType.java | 5 + .../api/type/builder/GeneratedTOBuilder.java | 7 +- .../builder/api/DataNodeContainerBuilder.java | 2 + .../parser/builder/api/UsesNodeBuilder.java | 8 +- .../impl/AugmentationSchemaBuilderImpl.java | 5 + .../builder/impl/LeafSchemaNodeBuilder.java | 2 + .../parser/builder/impl/ModuleBuilder.java | 11 + .../builder/impl/RpcDefinitionBuilder.java | 4 + .../builder/impl/UsesNodeBuilderImpl.java | 50 +- .../yang/parser/impl/YangParserImpl.java | 105 +- .../parser/impl/YangParserListenerImpl.java | 7 +- .../yang/parser/util/ParserUtils.java | 2 +- .../controller/yang/binding/BaseIdentity.java | 15 + .../yang/model/util/DataNodeIterator.java | 33 +- 23 files changed, 1107 insertions(+), 765 deletions(-) create mode 100644 opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferIdentityObject.java create mode 100644 opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/WildcardType.java create mode 100644 opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/BaseIdentity.java diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java index 863770d2c7..b89dbb44ac 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.sal.binding.generator.impl; import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl; import org.opendaylight.controller.binding.generator.util.Types; +import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl; import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator; import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider; @@ -23,6 +24,7 @@ import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair; import org.opendaylight.controller.yang.model.util.DataNodeIterator; import org.opendaylight.controller.yang.model.util.ExtendedType; +import org.opendaylight.controller.yang.model.util.SchemaContextUtil; import java.util.*; import java.util.concurrent.Future; @@ -65,6 +67,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { generatedTypes.addAll(allAugmentsToGenTypes(module)); generatedTypes.addAll(allRPCMethodsToGenType(module)); generatedTypes.addAll(allNotificationsToGenType(module)); + generatedTypes.addAll(allIdentitiesToGenTypes(module, context)); + generatedTypes.addAll(allGroupingsToGenTypes(module)); } return generatedTypes; } @@ -100,6 +104,9 @@ public final class BindingGeneratorImpl implements BindingGenerator { generatedTypes.addAll(allAugmentsToGenTypes(contextModule)); generatedTypes.addAll(allRPCMethodsToGenType(contextModule)); generatedTypes.addAll(allNotificationsToGenType(contextModule)); + generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, + context)); + generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); if (modules.contains(contextModule)) { filteredGenTypes.addAll(generatedTypes); @@ -397,6 +404,84 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genNotifyTypes; } + private List allIdentitiesToGenTypes(final Module module, + final SchemaContext context) { + List genTypes = new ArrayList(); + + final Set schemaIdentities = module.getIdentities(); + + final String basePackageName = moduleNamespaceToPackageName(module); + + if (schemaIdentities != null && !schemaIdentities.isEmpty()) { + for (final IdentitySchemaNode identity : schemaIdentities) { + genTypes.add(identityToGenType(basePackageName, identity, + context)); + } + } + return genTypes; + } + + private GeneratedType identityToGenType(final String basePackageName, + IdentitySchemaNode identity, SchemaContext context) { + if (identity == null) { + return null; + } + + final String packageName = packageNameForGeneratedType(basePackageName, + identity.getPath()); + + final String genTypeName = parseToClassName(identity.getQName() + .getLocalName()); + final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl( + packageName, genTypeName); + + IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); + if (baseIdentity != null) { + Module baseIdentityParentModule = SchemaContextUtil.findParentModule( + context, baseIdentity); + + final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); + final String returnTypeName = parseToClassName(baseIdentity + .getQName().getLocalName()); + + GeneratedTransferObject gto = new GeneratedTOBuilderImpl( + returnTypePkgName, returnTypeName).toInstance(); + newType.addExtendsType(gto); + } else { + newType.addExtendsType(Types.getBaseIdentityTO()); + } + + return newType.toIdentityInstance(); + } + + private List allGroupingsToGenTypes(Module module) { + final List genTypes = new ArrayList(); + final String basePackageName = moduleNamespaceToPackageName(module); + Set groupings = module.getGroupings(); + if (groupings != null && !groupings.isEmpty()) { + for (final GroupingDefinition grouping : groupings) { + genTypes.add(groupingToGenType(basePackageName, grouping)); + } + } + return genTypes; + } + + private GeneratedType groupingToGenType(final String basePackageName, + GroupingDefinition grouping) { + if (grouping == null) { + return null; + } + + final String packageName = packageNameForGeneratedType(basePackageName, + grouping.getPath()); + final Set schemaNodes = grouping.getChildNodes(); + final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition( + packageName, grouping); + + resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); + return typeBuilder.toInstance(); + } + private EnumTypeDefinition enumTypeDefFromExtendedType( final TypeDefinition typeDefinition) { if (typeDefinition != null) { diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java index 03824efed0..96069c273c 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java @@ -19,6 +19,7 @@ import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilde import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder; import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder; import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder; +import org.opendaylight.controller.yang.common.QName; import org.opendaylight.controller.yang.model.api.*; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair; @@ -103,7 +104,8 @@ public final class TypeProviderImpl implements TypeProvider { final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) baseTypeDef; returnType = provideTypeForLeafref(leafref); } else if (baseTypeDef instanceof IdentityrefTypeDefinition) { - + final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition)typeDefinition; + returnType = returnTypeForIdentityref(idref); } else if (baseTypeDef instanceof EnumTypeDefinition) { final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef; returnType = resolveEnumFromTypeDefinition(enumTypeDef, @@ -128,7 +130,8 @@ public final class TypeProviderImpl implements TypeProvider { final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition; returnType = provideTypeForLeafref(leafref); } else if (typeDefinition instanceof IdentityrefTypeDefinition) { - + final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition)typeDefinition; + returnType = returnTypeForIdentityref(idref); } else { returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER .javaTypeForSchemaDefinitionType(typeDefinition); @@ -142,6 +145,29 @@ public final class TypeProviderImpl implements TypeProvider { // } return returnType; } + + private Type returnTypeForIdentityref(IdentityrefTypeDefinition idref) { + QName baseIdQName = idref.getIdentity(); + Module module = schemaContext.findModuleByNamespace(baseIdQName.getNamespace()); + IdentitySchemaNode identity = null; + for(IdentitySchemaNode id : module.getIdentities()) { + if(id.getQName().equals(baseIdQName)) { + identity = id; + } + } + if(identity == null) { + throw new IllegalArgumentException("Target identity '" + baseIdQName + "' do not exists"); + } + + final String basePackageName = moduleNamespaceToPackageName(module); + final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath()); + final String genTypeName = parseToClassName(identity.getQName().getLocalName()); + + Type baseType = Types.typeForClass(Class.class); + Type paramType = Types.wildcardTypeFor(packageName, genTypeName); + Type returnType = Types.parameterizedTypeFor(baseType, paramType); + return returnType; + } public Type generatedTypeForExtendedDefinitionType( final TypeDefinition typeDefinition) { diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/Types.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/Types.java index 26be94351c..2e5bbf0a07 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/Types.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/Types.java @@ -11,11 +11,15 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; import org.opendaylight.controller.sal.binding.model.api.ConcreteType; +import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; import org.opendaylight.controller.sal.binding.model.api.ParameterizedType; import org.opendaylight.controller.sal.binding.model.api.Type; +import org.opendaylight.controller.sal.binding.model.api.WildcardType; import org.opendaylight.controller.yang.binding.Augmentable; import org.opendaylight.controller.yang.binding.Augmentation; +import org.opendaylight.controller.yang.binding.BaseIdentity; import org.opendaylight.controller.yang.binding.DataObject; public final class Types { @@ -36,7 +40,7 @@ public final class Types { /** * Returns an instance of {@link ConcreteType} describing the class - * + * * @param cls * Class to describe * @return Description of class @@ -49,7 +53,7 @@ public final class Types { /** * Returns an instance of {@link ParameterizedType} describing the typed * {@link Map} - * + * * @param keyType * Key Type * @param valueType @@ -63,7 +67,7 @@ public final class Types { /** * Returns an instance of {@link ParameterizedType} describing the typed * {@link Set} with concrete type of value. - * + * * @param valueType * Value Type * @return Description of generic type instance of Set @@ -75,7 +79,7 @@ public final class Types { /** * Returns an instance of {@link ParameterizedType} describing the typed * {@link List} with concrete type of value. - * + * * @param valueType * Value Type * @return Description of type instance of List @@ -84,8 +88,15 @@ public final class Types { return parameterizedTypeFor(LIST_TYPE, valueType); } + public static GeneratedTransferObject getBaseIdentityTO() { + Class cls = BaseIdentity.class; + GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(cls.getPackage().getName(), + cls.getSimpleName()); + return gto.toInstance(); + } + /** - * + * * @param type * @param parameters * @return @@ -94,17 +105,21 @@ public final class Types { Type... parameters) { return new ParametrizedTypeImpl(type, parameters); } - + + public static WildcardType wildcardTypeFor(String packageName, String typeName) { + return new WildcardTypeImpl(packageName, typeName); + } + public static ParameterizedType augmentableTypeFor(Type valueType) { final Type augmentable = typeForClass(Augmentable.class); return parameterizedTypeFor(augmentable, valueType); } - + public static ParameterizedType augmentationTypeFor(Type valueType) { final Type augmentation = typeForClass(Augmentation.class); return parameterizedTypeFor(augmentation, valueType); } - + private static class ConcreteTypeImpl extends AbstractBaseType implements ConcreteType { private ConcreteTypeImpl(String pkName, String name) { @@ -135,4 +150,12 @@ public final class Types { } } + + private static class WildcardTypeImpl extends AbstractBaseType + implements WildcardType { + public WildcardTypeImpl(String packageName, String typeName) { + super(packageName, typeName); + } + } + } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/GeneratedTOBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/GeneratedTOBuilderImpl.java index 558fb43850..f1683fdc64 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/GeneratedTOBuilderImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/GeneratedTOBuilderImpl.java @@ -16,6 +16,7 @@ import org.opendaylight.controller.sal.binding.model.api.AnnotationType; import org.opendaylight.controller.sal.binding.model.api.Constant; import org.opendaylight.controller.sal.binding.model.api.Enumeration; import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty; +import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferIdentityObject; import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; import org.opendaylight.controller.sal.binding.model.api.MethodSignature; import org.opendaylight.controller.sal.binding.model.api.Type; @@ -26,11 +27,11 @@ import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedP import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder; import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder; -public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { +public class GeneratedTOBuilderImpl implements GeneratedTOBuilder { private String packageName; private final String name; private String comment = ""; - + private GeneratedTransferObject extendsType; private final List implementsTypes = new ArrayList(); private final List enumerations = new ArrayList(); @@ -81,7 +82,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { } return null; } - + @Override public boolean addImplementsType(final Type genType) { if (genType != null) { @@ -98,7 +99,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { } return false; } - + @Override public EnumBuilder addEnumeration(String name) { final String innerPackageName = packageName + "." + this.name; @@ -149,10 +150,20 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { @Override public GeneratedTransferObject toInstance() { - return new GeneratedTransferObjectImpl(packageName, name, comment, - annotationBuilders, extendsType, implementsTypes, constantDefintions, enumerations, - methodDefinitions, properties, equalsProperties, - hashProperties, toStringProperties); + return new GeneratedTransferObjectImpl(packageName, name, comment, + annotationBuilders, extendsType, implementsTypes, + constantDefintions, enumerations, methodDefinitions, + properties, equalsProperties, hashProperties, + toStringProperties); + } + + @Override + public GeneratedTransferObject toIdentityInstance() { + return new GeneratedTransferIdentityObjectImpl(packageName, name, comment, + annotationBuilders, extendsType, implementsTypes, + constantDefintions, enumerations, methodDefinitions, + properties, equalsProperties, hashProperties, + toStringProperties); } private static final class GeneratedPropertyBuilderImpl implements @@ -227,8 +238,9 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { @Override public GeneratedProperty toInstance(final Type definingType) { - return new GeneratedPropertyImpl(name, comment, annotationBuilders, definingType, - returnType, isFinal, isReadOnly, parameters, accessModifier); + return new GeneratedPropertyImpl(name, comment, annotationBuilders, + definingType, returnType, isFinal, isReadOnly, parameters, + accessModifier); } } @@ -244,9 +256,10 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { private final boolean isReadOnly; private final List parameters; private final AccessModifier modifier; - + public GeneratedPropertyImpl(final String name, final String comment, - final List annotationBuilders, final Type parent, final Type returnType, + final List annotationBuilders, + final Type parent, final Type returnType, final boolean isFinal, final boolean isReadOnly, final List parameters, final AccessModifier modifier) { super(); @@ -284,7 +297,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { public List getAnnotations() { return annotations; } - + @Override public Type getReturnType() { return returnType; @@ -310,8 +323,6 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { return isFinal; } - - @Override public int hashCode() { final int prime = 31; @@ -354,7 +365,8 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { if (other.returnType != null) { return false; } - } else if (!returnType.getPackageName().equals(other.returnType.getPackageName())) { + } else if (!returnType.getPackageName().equals( + other.returnType.getPackageName())) { return false; } else if (!returnType.getName().equals(other.returnType.getName())) { return false; @@ -394,7 +406,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { } } - private static final class GeneratedTransferObjectImpl implements + private static class GeneratedTransferObjectImpl implements GeneratedTransferObject { private final String packageName; @@ -412,8 +424,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { private final List implementsTypes; public GeneratedTransferObjectImpl(final String packageName, - final String name, - final String comment, + final String name, final String comment, final List annotationBuilders, final GeneratedTransferObject extendsType, final List implementsTypes, @@ -430,7 +441,8 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { this.comment = comment; this.annotations = toUnmodifiableAnnotations(annotationBuilders); this.extendsType = extendsType; - this.implementsTypes = Collections.unmodifiableList(implementsTypes); + this.implementsTypes = Collections + .unmodifiableList(implementsTypes); this.constants = toUnmodifiableConstant(constantBuilders); this.enumerations = toUnmodifiableEnumerations(enumBuilders); this.properties = toUnmodifiableProperties(propBuilers); @@ -499,17 +511,17 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { public Type getParentType() { return null; } - + @Override public String getComment() { return comment; } - + @Override public List getAnnotations() { return annotations; } - + @Override public List getImplements() { return implementsTypes; @@ -519,7 +531,7 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { public GeneratedTransferObject getExtends() { return extendsType; } - + @Override public List getEnumDefintions() { return enumerations; @@ -623,4 +635,26 @@ public final class GeneratedTOBuilderImpl implements GeneratedTOBuilder { return builder.toString(); } } + + private static final class GeneratedTransferIdentityObjectImpl extends + GeneratedTransferObjectImpl implements + GeneratedTransferIdentityObject { + public GeneratedTransferIdentityObjectImpl(final String packageName, + final String name, final String comment, + final List annotationBuilders, + final GeneratedTransferObject extendsType, + final List implementsTypes, + final List constantBuilders, + final List enumBuilders, + final List methodBuilders, + final List propBuilers, + final List equalsBuilers, + final List hashCodeBuilers, + final List stringBuilers) { + super(packageName, name, comment, annotationBuilders, extendsType, + implementsTypes, constantBuilders, enumBuilders, + methodBuilders, propBuilers, equalsBuilers, + hashCodeBuilers, stringBuilers); + } + } } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java index 0dcaa71c13..aaeec40604 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java @@ -19,6 +19,7 @@ import java.util.Map; import org.opendaylight.controller.sal.binding.model.api.CodeGenerator; import org.opendaylight.controller.sal.binding.model.api.Enumeration; import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty; +import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferIdentityObject; import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; import org.opendaylight.controller.sal.binding.model.api.Type; @@ -29,6 +30,8 @@ public final class ClassCodeGenerator implements CodeGenerator { @Override public Writer generate(Type type) throws IOException { final Writer writer = new StringWriter(); + boolean isIdentity = type instanceof GeneratedTransferIdentityObject; + if (type instanceof GeneratedTransferObject) { GeneratedTransferObject genTO = (GeneratedTransferObject) type; imports = GeneratorUtil.createImports(genTO); @@ -47,7 +50,7 @@ public final class ClassCodeGenerator implements CodeGenerator { writer.write(NL); writer.write(GeneratorUtil.createClassDeclaration(genTO, "", - imports)); + imports, isIdentity)); writer.write(NL); writer.write(NL); @@ -66,7 +69,7 @@ public final class ClassCodeGenerator implements CodeGenerator { } writer.write(NL); writer.write(GeneratorUtil.createConstructor(genTO, TAB, - imports) + NL); + imports, isIdentity) + NL); writer.write(NL); for (GeneratedProperty field : fields) { writer.write(GeneratorUtil.createGetter(field, TAB, diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/Constants.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/Constants.java index bd94c20ffb..e5cb97f1a6 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/Constants.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/Constants.java @@ -8,7 +8,6 @@ package org.opendaylight.controller.sal.java.api.generator; final class Constants { - public static final String IFC = "interface"; public static final String CLASS = "class"; public static final String PKG = "package"; @@ -24,11 +23,13 @@ final class Constants { public static final String COMMA = ","; public static final String NL = "\n"; public static final String SC = ";"; - public static final String TAB = "\t"; + public static final String TAB = " "; public static final String PUBLIC = "public"; public static final String PRIVATE = "private"; + public static final String PROTECTED = "protected"; public static final String STATIC = "static"; + public static final String ABSTRACT = "abstract"; public static final String FINAL = "final"; public static final String EXTENDS = "extends"; public static final String IMPLEMENTS = "implements"; diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java index bb4bbbaf78..5b3b17dbf6 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java @@ -26,670 +26,692 @@ import org.opendaylight.controller.sal.binding.model.api.MethodSignature; import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter; import org.opendaylight.controller.sal.binding.model.api.ParameterizedType; import org.opendaylight.controller.sal.binding.model.api.Type; +import org.opendaylight.controller.sal.binding.model.api.WildcardType; public final class GeneratorUtil { - private GeneratorUtil() { - } - - public static String createIfcDeclaration(final GeneratedType genType, - final String indent, - final Map> availableImports) { - return createFileDeclaration(IFC, genType, indent, availableImports); - } - - public static String createClassDeclaration( - final GeneratedTransferObject genTransferObject, - final String indent, - final Map> availableImports) { - return createFileDeclaration(CLASS, genTransferObject, indent, - availableImports); - } - - public static String createPackageDeclaration(final String packageName) { - return PKG + GAP + packageName + SC; - } - - private static String createFileDeclaration(final String type, - final GeneratedType genType, final String indent, - final Map> availableImports) { - final StringBuilder builder = new StringBuilder(); - final String currentPkg = genType.getPackageName(); - - createComment(builder, genType.getComment(), indent); - - if (!genType.getAnnotations().isEmpty()) { - final List annotations = genType.getAnnotations(); - appendAnnotations(builder, annotations); - builder.append(NL); - } - builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP); - - if (genType instanceof GeneratedTransferObject) { - GeneratedTransferObject genTO = (GeneratedTransferObject) genType; - - if (genTO.getExtends() != null) { - builder.append(EXTENDS + GAP); - builder.append(genTO.getExtends() + GAP); - } - } - - final List genImplements = genType.getImplements(); - if (!genImplements.isEmpty()) { - if (genType instanceof GeneratedTransferObject) { - builder.append(IMPLEMENTS + GAP); - } else { - builder.append(EXTENDS + GAP); - } - builder.append(getExplicitType(genImplements.get(0), - availableImports, currentPkg)); - - for (int i = 1; i < genImplements.size(); ++i) { - builder.append(", "); - builder.append(getExplicitType(genImplements.get(i), - availableImports, currentPkg)); - } - } - - builder.append(GAP + LCB); - return builder.toString(); - } - - private static StringBuilder appendAnnotations(final StringBuilder builder, - final List annotations) { - if ((builder != null) && (annotations != null)) { - for (final AnnotationType annotation : annotations) { - builder.append("@"); - builder.append(annotation.getPackageName()); - builder.append("."); - builder.append(annotation.getName()); - - if (annotation.containsParameters()) { - builder.append("("); - final List parameters = annotation - .getParameters(); - appendAnnotationParams(builder, parameters); - builder.append(")"); - } - } - } - return builder; - } - - private static StringBuilder appendAnnotationParams( - final StringBuilder builder, - final List parameters) { - if (parameters != null) { - int i = 0; - for (final AnnotationType.Parameter param : parameters) { - if (param == null) { - continue; - } - if (i > 0) { - builder.append(", "); - } - final String paramName = param.getName(); - if (param.getValue() != null) { - builder.append(paramName); - builder.append(" = "); - builder.append(param.getValue()); - } else { - builder.append(paramName); - builder.append(" = {"); - final List values = param.getValues(); - builder.append(values.get(0)); - for (int j = 1; j < values.size(); ++j) { - builder.append(", "); - builder.append(values.get(j)); - } - builder.append("}"); - } - i++; - } - } - return builder; - } - - public static String createConstant(final Constant constant, - final String indent, - final Map> availableImports, - final String currentPkg) { - final StringBuilder builder = new StringBuilder(); - builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP); - builder.append(getExplicitType(constant.getType(), availableImports, - currentPkg) + GAP + constant.getName()); - builder.append(GAP + "=" + GAP); - builder.append(constant.getValue() + SC); - return builder.toString(); - } - - public static String createField(final GeneratedProperty property, - final String indent, - Map> availableImports, - final String currentPkg) { - final StringBuilder builder = new StringBuilder(); - builder.append(indent); - if (!property.getAnnotations().isEmpty()) { - final List annotations = property.getAnnotations(); - appendAnnotations(builder, annotations); - builder.append(NL); - } - builder.append(indent + PRIVATE + GAP); - builder.append(getExplicitType(property.getReturnType(), - availableImports, currentPkg) + GAP + property.getName()); - builder.append(SC); - return builder.toString(); - } - - /** - * Create method declaration in interface. - * - * @param method - * @param indent - * @return - */ - public static String createMethodDeclaration(final MethodSignature method, - final String indent, - Map> availableImports, - final String currentPkg) { - final StringBuilder builder = new StringBuilder(); - - if (method == null) { - throw new IllegalArgumentException( - "Method Signature parameter MUST be specified and cannot be NULL!"); - } - - final String comment = method.getComment(); - final String name = method.getName(); - if (name == null) { - throw new IllegalStateException("Method Name cannot be NULL!"); - } - - final Type type = method.getReturnType(); - if (type == null) { - throw new IllegalStateException( - "Method Return type cannot be NULL!"); - } - - final List parameters = method.getParameters(); - - createComment(builder, comment, indent); - builder.append(NL); - builder.append(indent); - - if (!method.getAnnotations().isEmpty()) { - final List annotations = method.getAnnotations(); - appendAnnotations(builder, annotations); - builder.append(NL); - } - - builder.append(indent - + getExplicitType(type, availableImports, currentPkg) + GAP - + name); - builder.append(LB); - for (int i = 0; i < parameters.size(); i++) { - Parameter p = parameters.get(i); - String separator = COMMA; - if (i + 1 == parameters.size()) { - separator = ""; - } - builder.append(getExplicitType(p.getType(), availableImports, - currentPkg) + GAP + p.getName() + separator); - } - builder.append(RB); - builder.append(SC); - - return builder.toString(); - } - - public static String createConstructor( - GeneratedTransferObject genTransferObject, final String indent, - Map> availableImports) { - final StringBuilder builder = new StringBuilder(); - - final String currentPkg = genTransferObject.getPackageName(); - final List properties = genTransferObject - .getProperties(); - final List ctorParams = new ArrayList(); - for (final GeneratedProperty property : properties) { - if (property.isReadOnly()) { - ctorParams.add(property); - } - } - - builder.append(indent); - builder.append(PUBLIC); - builder.append(GAP); - builder.append(genTransferObject.getName()); - builder.append(LB); - - if (!ctorParams.isEmpty()) { - builder.append(getExplicitType(ctorParams.get(0).getReturnType(), - availableImports, currentPkg)); - builder.append(" "); - builder.append(ctorParams.get(0).getName()); - for (int i = 1; i < ctorParams.size(); ++i) { - final GeneratedProperty param = ctorParams.get(i); - builder.append(", "); - builder.append(getExplicitType(param.getReturnType(), - availableImports, currentPkg)); - builder.append(GAP); - builder.append(param.getName()); - } - } - builder.append(RB + GAP + LCB + NL + indent + TAB + "super();" + NL); - if (!ctorParams.isEmpty()) { - for (final GeneratedProperty property : ctorParams) { - builder.append(indent); - builder.append(TAB); - builder.append("this."); - builder.append(property.getName()); - builder.append(" = "); - builder.append(property.getName()); - builder.append(SC); - builder.append(NL); - } - } - builder.append(indent); - builder.append(RCB); - return builder.toString(); - } - - public static String createGetter(final GeneratedProperty property, - final String indent, - Map> availableImports, - final String currentPkg) { - final StringBuilder builder = new StringBuilder(); - - final Type type = property.getReturnType(); - final String varName = property.getName(); - final char first = Character.toUpperCase(varName.charAt(0)); - final String methodName = "get" + first + varName.substring(1); - - builder.append(indent + PUBLIC + GAP - + getExplicitType(type, availableImports, currentPkg) + GAP - + methodName); - builder.append(LB + RB + LCB + NL); - - String currentIndent = indent + TAB; - - builder.append(currentIndent + "return " + varName + SC + NL); - - builder.append(indent + RCB); - return builder.toString(); - } - - public static String createSetter(final GeneratedProperty property, - final String indent, - Map> availableImports, - String currentPkg) { - final StringBuilder builder = new StringBuilder(); - - final Type type = property.getReturnType(); - final String varName = property.getName(); - final char first = Character.toUpperCase(varName.charAt(0)); - final String methodName = "set" + first + varName.substring(1); - - builder.append(indent + PUBLIC + GAP + "void" + GAP + methodName); - builder.append(LB + getExplicitType(type, availableImports, currentPkg) - + GAP + varName + RB + LCB + NL); - String currentIndent = indent + TAB; - builder.append(currentIndent + "this." + varName + " = " + varName + SC - + NL); - builder.append(indent + RCB); - return builder.toString(); - } - - public static String createHashCode( - final List properties, final String indent) { - StringBuilder builder = new StringBuilder(); - builder.append(indent + "public int hashCode() {" + NL); - builder.append(indent + TAB + "final int prime = 31;" + NL); - builder.append(indent + TAB + "int result = 1;" + NL); - - for (GeneratedProperty property : properties) { - String fieldName = property.getName(); - builder.append(indent + TAB + "result = prime * result + ((" - + fieldName + " == null) ? 0 : " + fieldName - + ".hashCode());" + NL); - } - - builder.append(indent + TAB + "return result;" + NL); - builder.append(indent + RCB + NL); - return builder.toString(); - } - - public static String createEquals(final GeneratedTransferObject type, - final List properties, final String indent) { - StringBuilder builder = new StringBuilder(); - final String indent1 = indent + TAB; - final String indent2 = indent1 + TAB; - final String indent3 = indent2 + TAB; - - builder.append(indent + "public boolean equals(Object obj) {" + NL); - builder.append(indent1 + "if (this == obj) {" + NL); - builder.append(indent2 + "return true;" + NL); - builder.append(indent1 + "}" + NL); - builder.append(indent1 + "if (obj == null) {" + NL); - builder.append(indent2 + "return false;" + NL); - builder.append(indent1 + "}" + NL); - builder.append(indent1 + "if (getClass() != obj.getClass()) {" + NL); - builder.append(indent2 + "return false;" + NL); - builder.append(indent1 + "}" + NL); - - String typeStr = type.getName(); - builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;" - + NL); - - for (GeneratedProperty property : properties) { - String fieldName = property.getName(); - builder.append(indent1 + "if (" + fieldName + " == null) {" + NL); - builder.append(indent2 + "if (other." + fieldName + " != null) {" - + NL); - builder.append(indent3 + "return false;" + NL); - builder.append(indent2 + "}" + NL); - builder.append(indent1 + "} else if (!" + fieldName - + ".equals(other." + fieldName + ")) {" + NL); - builder.append(indent2 + "return false;" + NL); - builder.append(indent1 + "}" + NL); - } - - builder.append(indent1 + "return true;" + NL); - - builder.append(indent + RCB + NL); - return builder.toString(); - } - - public static String createToString(final GeneratedTransferObject type, - final List properties, final String indent) { - StringBuilder builder = new StringBuilder(); - builder.append(indent); - builder.append("public String toString() {"); - builder.append(NL); - builder.append(indent); - builder.append(TAB); - builder.append("StringBuilder builder = new StringBuilder();"); - builder.append(NL); - builder.append(indent); - builder.append(TAB); - builder.append("builder.append(\""); - builder.append(type.getName()); - builder.append(" ["); - - boolean first = true; - for (GeneratedProperty property : properties) { - if (first) { - builder.append(property.getName()); - builder.append("=\");"); - builder.append(NL); - builder.append(indent); - builder.append(TAB); - builder.append("builder.append("); - builder.append(property.getName()); - builder.append(");"); - first = false; - } else { - builder.append(NL); - builder.append(indent); - builder.append(TAB); - builder.append("builder.append(\", "); - builder.append(property.getName()); - builder.append("=\");"); - builder.append(NL); - builder.append(indent); - builder.append(TAB); - builder.append("builder.append("); - builder.append(property.getName()); - builder.append(");"); - } - } - builder.append(NL); - builder.append(indent); - builder.append(TAB); - builder.append("builder.append(\"]\");"); - builder.append(NL); - builder.append(indent); - builder.append(TAB); - builder.append("return builder.toString();"); - - builder.append(NL); - builder.append(indent); - builder.append(RCB); - builder.append(NL); - return builder.toString(); - } - - public static String createEnum(final Enumeration enumeration, - final String indent) { - if (enumeration == null || indent == null) - throw new IllegalArgumentException(); - final StringBuilder builder = new StringBuilder(indent + PUBLIC + GAP - + ENUM + GAP + enumeration.getName() + GAP + LCB + NL); - - String separator = COMMA + NL; - final List values = enumeration.getValues(); - - for (int i = 0; i < values.size(); i++) { - if (i + 1 == values.size()) { - separator = SC; - } - builder.append(indent + TAB + values.get(i).getName() + LB - + values.get(i).getValue() + RB + separator); - } - builder.append(NL); - builder.append(NL); - final String ENUMERATION_NAME = "value"; - final String ENUMERATION_TYPE = "int"; - builder.append(indent + TAB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME - + SC); - builder.append(NL); - builder.append(indent + TAB + PRIVATE + GAP + enumeration.getName() - + LB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME + RB + GAP - + LCB + NL); - builder.append(indent + TAB + TAB + "this." + ENUMERATION_NAME + GAP - + "=" + GAP + ENUMERATION_NAME + SC + NL); - builder.append(indent + TAB + RCB + NL); - - builder.append(indent + RCB); - builder.append(NL); - return builder.toString(); - } - - private static String getExplicitType(final Type type, - Map> availableImports, - final String currentPkg) { - if (type == null) { - throw new IllegalArgumentException( - "Type parameter MUST be specified and cannot be NULL!"); - } - String packageName = type.getPackageName(); - - LinkedHashMap imports = availableImports.get(type - .getName()); - - if ((imports != null && packageName - .equals(findMaxValue(imports).get(0))) - || packageName.equals(currentPkg)) { - final StringBuilder builder = new StringBuilder(type.getName()); - if (type instanceof ParameterizedType) { - ParameterizedType pType = (ParameterizedType) type; - Type[] pTypes = pType.getActualTypeArguments(); - builder.append("<"); - builder.append(getParameters(pTypes, availableImports, - currentPkg)); - builder.append(">"); - } - if (builder.toString().equals("Void")) { - return "void"; - } - return builder.toString(); - } else { - final StringBuilder builder = new StringBuilder(); - if (packageName.startsWith("java.lang")) { - builder.append(type.getName()); - } else { + private GeneratorUtil() { + } + + public static String createIfcDeclaration(final GeneratedType genType, + final String indent, + final Map> availableImports) { + return createFileDeclaration(IFC, genType, indent, availableImports, + false); + } + + public static String createClassDeclaration( + final GeneratedTransferObject genTransferObject, + final String indent, + final Map> availableImports, + boolean isIdentity) { + return createFileDeclaration(CLASS, genTransferObject, indent, + availableImports, isIdentity); + } + + public static String createPackageDeclaration(final String packageName) { + return PKG + GAP + packageName + SC; + } + + private static String createFileDeclaration(final String type, + final GeneratedType genType, final String indent, + final Map> availableImports, + boolean isIdentity) { + final StringBuilder builder = new StringBuilder(); + final String currentPkg = genType.getPackageName(); + + createComment(builder, genType.getComment(), indent); + + if (!genType.getAnnotations().isEmpty()) { + final List annotations = genType.getAnnotations(); + appendAnnotations(builder, annotations); + builder.append(NL); + } + + if (isIdentity) { + if (!(CLASS.equals(type))) { + throw new IllegalArgumentException( + "'identity' has to be generated as a class"); + } + builder.append(PUBLIC + GAP + ABSTRACT + GAP + type + GAP + + genType.getName() + GAP); + } else { + builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP); + } + + if (genType instanceof GeneratedTransferObject) { + GeneratedTransferObject genTO = (GeneratedTransferObject) genType; + + if (genTO.getExtends() != null) { + builder.append(EXTENDS + GAP); + String gtoString = getExplicitType(genTO.getExtends(), availableImports, currentPkg); + builder.append(gtoString + GAP); + } + } + + final List genImplements = genType.getImplements(); + if (!genImplements.isEmpty()) { + if (genType instanceof GeneratedTransferObject) { + builder.append(IMPLEMENTS + GAP); + } else { + builder.append(EXTENDS + GAP); + } + builder.append(getExplicitType(genImplements.get(0), + availableImports, currentPkg)); + + for (int i = 1; i < genImplements.size(); ++i) { + builder.append(", "); + builder.append(getExplicitType(genImplements.get(i), + availableImports, currentPkg)); + } + } + + builder.append(GAP + LCB); + return builder.toString(); + } + + private static StringBuilder appendAnnotations(final StringBuilder builder, + final List annotations) { + if ((builder != null) && (annotations != null)) { + for (final AnnotationType annotation : annotations) { + builder.append("@"); + builder.append(annotation.getPackageName()); + builder.append("."); + builder.append(annotation.getName()); + + if (annotation.containsParameters()) { + builder.append("("); + final List parameters = annotation + .getParameters(); + appendAnnotationParams(builder, parameters); + builder.append(")"); + } + } + } + return builder; + } + + private static StringBuilder appendAnnotationParams( + final StringBuilder builder, + final List parameters) { + if (parameters != null) { + int i = 0; + for (final AnnotationType.Parameter param : parameters) { + if (param == null) { + continue; + } + if (i > 0) { + builder.append(", "); + } + final String paramName = param.getName(); + if (param.getValue() != null) { + builder.append(paramName); + builder.append(" = "); + builder.append(param.getValue()); + } else { + builder.append(paramName); + builder.append(" = {"); + final List values = param.getValues(); + builder.append(values.get(0)); + for (int j = 1; j < values.size(); ++j) { + builder.append(", "); + builder.append(values.get(j)); + } + builder.append("}"); + } + i++; + } + } + return builder; + } + + public static String createConstant(final Constant constant, + final String indent, + final Map> availableImports, + final String currentPkg) { + final StringBuilder builder = new StringBuilder(); + builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP); + builder.append(getExplicitType(constant.getType(), availableImports, + currentPkg) + GAP + constant.getName()); + builder.append(GAP + "=" + GAP); + builder.append(constant.getValue() + SC); + return builder.toString(); + } + + public static String createField(final GeneratedProperty property, + final String indent, + Map> availableImports, + final String currentPkg) { + final StringBuilder builder = new StringBuilder(); + if (!property.getAnnotations().isEmpty()) { + final List annotations = property.getAnnotations(); + appendAnnotations(builder, annotations); + builder.append(NL); + } + builder.append(indent + PRIVATE + GAP); + builder.append(getExplicitType(property.getReturnType(), + availableImports, currentPkg) + GAP + property.getName()); + builder.append(SC); + return builder.toString(); + } + + /** + * Create method declaration in interface. + * + * @param method + * @param indent + * @return + */ + public static String createMethodDeclaration(final MethodSignature method, + final String indent, + Map> availableImports, + final String currentPkg) { + final StringBuilder builder = new StringBuilder(); + + if (method == null) { + throw new IllegalArgumentException( + "Method Signature parameter MUST be specified and cannot be NULL!"); + } + + final String comment = method.getComment(); + final String name = method.getName(); + if (name == null) { + throw new IllegalStateException("Method Name cannot be NULL!"); + } + + final Type type = method.getReturnType(); + if (type == null) { + throw new IllegalStateException( + "Method Return type cannot be NULL!"); + } + + final List parameters = method.getParameters(); + + createComment(builder, comment, indent); + builder.append(NL); + builder.append(indent); + + if (!method.getAnnotations().isEmpty()) { + final List annotations = method.getAnnotations(); + appendAnnotations(builder, annotations); + builder.append(NL); + } + + builder.append(indent + + getExplicitType(type, availableImports, currentPkg) + GAP + + name); + builder.append(LB); + for (int i = 0; i < parameters.size(); i++) { + Parameter p = parameters.get(i); + String separator = COMMA; + if (i + 1 == parameters.size()) { + separator = ""; + } + builder.append(getExplicitType(p.getType(), availableImports, + currentPkg) + GAP + p.getName() + separator); + } + builder.append(RB); + builder.append(SC); + + return builder.toString(); + } + + public static String createConstructor( + GeneratedTransferObject genTransferObject, final String indent, + Map> availableImports, + boolean isIdentity) { + final StringBuilder builder = new StringBuilder(); + + final String currentPkg = genTransferObject.getPackageName(); + final List properties = genTransferObject + .getProperties(); + final List ctorParams = new ArrayList(); + for (final GeneratedProperty property : properties) { + if (property.isReadOnly()) { + ctorParams.add(property); + } + } + + builder.append(indent); + builder.append(isIdentity ? PROTECTED : PUBLIC); + builder.append(GAP); + builder.append(genTransferObject.getName()); + builder.append(LB); + + if (!ctorParams.isEmpty()) { + builder.append(getExplicitType(ctorParams.get(0).getReturnType(), + availableImports, currentPkg)); + builder.append(" "); + builder.append(ctorParams.get(0).getName()); + for (int i = 1; i < ctorParams.size(); ++i) { + final GeneratedProperty param = ctorParams.get(i); + builder.append(", "); + builder.append(getExplicitType(param.getReturnType(), + availableImports, currentPkg)); + builder.append(GAP); + builder.append(param.getName()); + } + } + builder.append(RB + GAP + LCB + NL + indent + TAB + "super();" + NL); + if (!ctorParams.isEmpty()) { + for (final GeneratedProperty property : ctorParams) { + builder.append(indent); + builder.append(TAB); + builder.append("this."); + builder.append(property.getName()); + builder.append(" = "); + builder.append(property.getName()); + builder.append(SC); + builder.append(NL); + } + } + builder.append(indent); + builder.append(RCB); + return builder.toString(); + } + + public static String createGetter(final GeneratedProperty property, + final String indent, + Map> availableImports, + final String currentPkg) { + final StringBuilder builder = new StringBuilder(); + + final Type type = property.getReturnType(); + final String varName = property.getName(); + final char first = Character.toUpperCase(varName.charAt(0)); + final String methodName = "get" + first + varName.substring(1); + + builder.append(indent + PUBLIC + GAP + + getExplicitType(type, availableImports, currentPkg) + GAP + + methodName); + builder.append(LB + RB + LCB + NL); + + String currentIndent = indent + TAB; + + builder.append(currentIndent + "return " + varName + SC + NL); + + builder.append(indent + RCB); + return builder.toString(); + } + + public static String createSetter(final GeneratedProperty property, + final String indent, + Map> availableImports, + String currentPkg) { + final StringBuilder builder = new StringBuilder(); + + final Type type = property.getReturnType(); + final String varName = property.getName(); + final char first = Character.toUpperCase(varName.charAt(0)); + final String methodName = "set" + first + varName.substring(1); + + builder.append(indent + PUBLIC + GAP + "void" + GAP + methodName); + builder.append(LB + getExplicitType(type, availableImports, currentPkg) + + GAP + varName + RB + LCB + NL); + String currentIndent = indent + TAB; + builder.append(currentIndent + "this." + varName + " = " + varName + SC + + NL); + builder.append(indent + RCB); + return builder.toString(); + } + + public static String createHashCode( + final List properties, final String indent) { + StringBuilder builder = new StringBuilder(); + builder.append(indent + "public int hashCode() {" + NL); + builder.append(indent + TAB + "final int prime = 31;" + NL); + builder.append(indent + TAB + "int result = 1;" + NL); + + for (GeneratedProperty property : properties) { + String fieldName = property.getName(); + builder.append(indent + TAB + "result = prime * result + ((" + + fieldName + " == null) ? 0 : " + fieldName + + ".hashCode());" + NL); + } + + builder.append(indent + TAB + "return result;" + NL); + builder.append(indent + RCB + NL); + return builder.toString(); + } + + public static String createEquals(final GeneratedTransferObject type, + final List properties, final String indent) { + StringBuilder builder = new StringBuilder(); + final String indent1 = indent + TAB; + final String indent2 = indent1 + TAB; + final String indent3 = indent2 + TAB; + + builder.append(indent + "public boolean equals(Object obj) {" + NL); + builder.append(indent1 + "if (this == obj) {" + NL); + builder.append(indent2 + "return true;" + NL); + builder.append(indent1 + "}" + NL); + builder.append(indent1 + "if (obj == null) {" + NL); + builder.append(indent2 + "return false;" + NL); + builder.append(indent1 + "}" + NL); + builder.append(indent1 + "if (getClass() != obj.getClass()) {" + NL); + builder.append(indent2 + "return false;" + NL); + builder.append(indent1 + "}" + NL); + + String typeStr = type.getName(); + builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;" + + NL); + + for (GeneratedProperty property : properties) { + String fieldName = property.getName(); + builder.append(indent1 + "if (" + fieldName + " == null) {" + NL); + builder.append(indent2 + "if (other." + fieldName + " != null) {" + + NL); + builder.append(indent3 + "return false;" + NL); + builder.append(indent2 + "}" + NL); + builder.append(indent1 + "} else if (!" + fieldName + + ".equals(other." + fieldName + ")) {" + NL); + builder.append(indent2 + "return false;" + NL); + builder.append(indent1 + "}" + NL); + } + + builder.append(indent1 + "return true;" + NL); + + builder.append(indent + RCB + NL); + return builder.toString(); + } + + public static String createToString(final GeneratedTransferObject type, + final List properties, final String indent) { + StringBuilder builder = new StringBuilder(); + builder.append(indent); + builder.append("public String toString() {"); + builder.append(NL); + builder.append(indent); + builder.append(TAB); + builder.append("StringBuilder builder = new StringBuilder();"); + builder.append(NL); + builder.append(indent); + builder.append(TAB); + builder.append("builder.append(\""); + builder.append(type.getName()); + builder.append(" ["); + + boolean first = true; + for (GeneratedProperty property : properties) { + if (first) { + builder.append(property.getName()); + builder.append("=\");"); + builder.append(NL); + builder.append(indent); + builder.append(TAB); + builder.append("builder.append("); + builder.append(property.getName()); + builder.append(");"); + first = false; + } else { + builder.append(NL); + builder.append(indent); + builder.append(TAB); + builder.append("builder.append(\", "); + builder.append(property.getName()); + builder.append("=\");"); + builder.append(NL); + builder.append(indent); + builder.append(TAB); + builder.append("builder.append("); + builder.append(property.getName()); + builder.append(");"); + } + } + builder.append(NL); + builder.append(indent); + builder.append(TAB); + builder.append("builder.append(\"]\");"); + builder.append(NL); + builder.append(indent); + builder.append(TAB); + builder.append("return builder.toString();"); + + builder.append(NL); + builder.append(indent); + builder.append(RCB); + builder.append(NL); + return builder.toString(); + } + + public static String createEnum(final Enumeration enumeration, + final String indent) { + if (enumeration == null || indent == null) + throw new IllegalArgumentException(); + final StringBuilder builder = new StringBuilder(indent + PUBLIC + GAP + + ENUM + GAP + enumeration.getName() + GAP + LCB + NL); + + String separator = COMMA + NL; + final List values = enumeration.getValues(); + + for (int i = 0; i < values.size(); i++) { + if (i + 1 == values.size()) { + separator = SC; + } + builder.append(indent + TAB + values.get(i).getName() + LB + + values.get(i).getValue() + RB + separator); + } + builder.append(NL); + builder.append(NL); + final String ENUMERATION_NAME = "value"; + final String ENUMERATION_TYPE = "int"; + builder.append(indent + TAB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME + + SC); + builder.append(NL); + builder.append(indent + TAB + PRIVATE + GAP + enumeration.getName() + + LB + ENUMERATION_TYPE + GAP + ENUMERATION_NAME + RB + GAP + + LCB + NL); + builder.append(indent + TAB + TAB + "this." + ENUMERATION_NAME + GAP + + "=" + GAP + ENUMERATION_NAME + SC + NL); + builder.append(indent + TAB + RCB + NL); + + builder.append(indent + RCB); + builder.append(NL); + return builder.toString(); + } + + private static String getExplicitType(final Type type, + Map> availableImports, + final String currentPkg) { + if (type == null) { + throw new IllegalArgumentException( + "Type parameter MUST be specified and cannot be NULL!"); + } + String packageName = type.getPackageName(); + + LinkedHashMap imports = availableImports.get(type + .getName()); + + if ((imports != null && packageName + .equals(findMaxValue(imports).get(0))) + || packageName.equals(currentPkg)) { + final StringBuilder builder = new StringBuilder(type.getName()); + if (type instanceof ParameterizedType) { + ParameterizedType pType = (ParameterizedType) type; + Type[] pTypes = pType.getActualTypeArguments(); + builder.append("<"); + builder.append(getParameters(pTypes, availableImports, + currentPkg)); + builder.append(">"); + } + if (builder.toString().equals("Void")) { + return "void"; + } + return builder.toString(); + } else { + final StringBuilder builder = new StringBuilder(); + if (packageName.startsWith("java.lang")) { + builder.append(type.getName()); + } else { if (!packageName.isEmpty()) { builder.append(packageName + "." + type.getName()); } else { builder.append(type.getName()); } - } - if (type instanceof ParameterizedType) { - ParameterizedType pType = (ParameterizedType) type; - Type[] pTypes = pType.getActualTypeArguments(); - builder.append("<"); - builder.append(getParameters(pTypes, availableImports, - currentPkg)); - builder.append(">"); - } - if (builder.toString().equals("Void")) { - return "void"; - } - return builder.toString(); - } - } - - private static String getParameters(final Type[] pTypes, - Map> availableImports, - String currentPkg) { - final StringBuilder builder = new StringBuilder(); - for (int i = 0; i < pTypes.length; i++) { - Type t = pTypes[i]; - - String separator = COMMA; - if (i + 1 == pTypes.length) { - separator = ""; - } - builder.append(getExplicitType(t, availableImports, currentPkg) - + separator); - } - return builder.toString(); - } - - private static List findMaxValue( - LinkedHashMap imports) { - final List result = new ArrayList(); - - int maxValue = 0; - int currentValue = 0; - for (Map.Entry entry : imports.entrySet()) { - currentValue = entry.getValue(); - if (currentValue > maxValue) { - result.clear(); - result.add(entry.getKey()); - } else if (currentValue == maxValue) { - result.add(entry.getKey()); - } - } - return result; - } - - private static void createComment(final StringBuilder builder, - final String comment, final String indent) { - if (comment != null && comment.length() > 0) { - builder.append(indent + "/*" + NL); - builder.append(indent + comment + NL); - builder.append(indent + "*/" + NL); - } - } - - public static Map> createImports( - GeneratedType genType) { - final Map> imports = new HashMap>(); - final String genTypePkg = genType.getPackageName(); - - final List constants = genType.getConstantDefinitions(); - final List methods = genType.getMethodDefinitions(); - List impl = genType.getImplements(); - - // IMPLEMENTATIONS - if (impl != null) { - for (Type t : impl) { - addTypeToImports(t, imports, genTypePkg); - } - } - - // CONSTANTS - if (constants != null) { - for (Constant c : constants) { - Type ct = c.getType(); - addTypeToImports(ct, imports, genTypePkg); - } - } - - // METHODS - if (methods != null) { - for (MethodSignature m : methods) { - Type ct = m.getReturnType(); - addTypeToImports(ct, imports, genTypePkg); - for (MethodSignature.Parameter p : m.getParameters()) { - addTypeToImports(p.getType(), imports, genTypePkg); - } - } - } - - // PROPERTIES - if (genType instanceof GeneratedTransferObject) { - GeneratedTransferObject genTO = (GeneratedTransferObject) genType; - - List props = genTO.getProperties(); - if (props != null) { - for (GeneratedProperty prop : props) { - Type pt = prop.getReturnType(); - addTypeToImports(pt, imports, genTypePkg); - } - } - } - - return imports; - } - - private static void addTypeToImports(Type type, - Map> importedTypes, - String genTypePkg) { - String typeName = type.getName(); - String typePkg = type.getPackageName(); + } + if (type instanceof ParameterizedType) { + ParameterizedType pType = (ParameterizedType) type; + Type[] pTypes = pType.getActualTypeArguments(); + builder.append("<"); + builder.append(getParameters(pTypes, availableImports, + currentPkg)); + builder.append(">"); + } + if (builder.toString().equals("Void")) { + return "void"; + } + return builder.toString(); + } + } + + private static String getParameters(final Type[] pTypes, + Map> availableImports, + String currentPkg) { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < pTypes.length; i++) { + Type t = pTypes[i]; + + String separator = COMMA; + if (i + 1 == pTypes.length) { + separator = ""; + } + + String wildcardParam = ""; + if(t instanceof WildcardType) { + wildcardParam = "? extends "; + } + + builder.append(wildcardParam + getExplicitType(t, availableImports, currentPkg) + + separator); + } + return builder.toString(); + } + + private static List findMaxValue( + LinkedHashMap imports) { + final List result = new ArrayList(); + + int maxValue = 0; + int currentValue = 0; + for (Map.Entry entry : imports.entrySet()) { + currentValue = entry.getValue(); + if (currentValue > maxValue) { + result.clear(); + result.add(entry.getKey()); + maxValue = currentValue; + } else if (currentValue == maxValue) { + result.add(entry.getKey()); + } + } + return result; + } + + private static void createComment(final StringBuilder builder, + final String comment, final String indent) { + if (comment != null && comment.length() > 0) { + builder.append(indent + "/*" + NL); + builder.append(indent + comment + NL); + builder.append(indent + "*/" + NL); + } + } + + public static Map> createImports( + GeneratedType genType) { + final Map> imports = new HashMap>(); + final String genTypePkg = genType.getPackageName(); + + final List constants = genType.getConstantDefinitions(); + final List methods = genType.getMethodDefinitions(); + List impl = genType.getImplements(); + + // IMPLEMENTATIONS + if (impl != null) { + for (Type t : impl) { + addTypeToImports(t, imports, genTypePkg); + } + } + + // CONSTANTS + if (constants != null) { + for (Constant c : constants) { + Type ct = c.getType(); + addTypeToImports(ct, imports, genTypePkg); + } + } + + // METHODS + if (methods != null) { + for (MethodSignature m : methods) { + Type ct = m.getReturnType(); + addTypeToImports(ct, imports, genTypePkg); + for (MethodSignature.Parameter p : m.getParameters()) { + addTypeToImports(p.getType(), imports, genTypePkg); + } + } + } + + // PROPERTIES + if (genType instanceof GeneratedTransferObject) { + GeneratedTransferObject genTO = (GeneratedTransferObject) genType; + + List props = genTO.getProperties(); + if (props != null) { + for (GeneratedProperty prop : props) { + Type pt = prop.getReturnType(); + addTypeToImports(pt, imports, genTypePkg); + } + } + } + + return imports; + } + + private static void addTypeToImports(Type type, + Map> importedTypes, + String genTypePkg) { + String typeName = type.getName(); + String typePkg = type.getPackageName(); if (typePkg.startsWith("java.lang") || typePkg.equals(genTypePkg) || typePkg.isEmpty()) { - return; - } - LinkedHashMap packages = importedTypes.get(typeName); - if (packages == null) { - packages = new LinkedHashMap(); - packages.put(typePkg, 1); - importedTypes.put(typeName, packages); - } else { - Integer occurrence = packages.get(typePkg); - if (occurrence == null) { - packages.put(typePkg, 1); - } else { - occurrence++; - packages.put(typePkg, occurrence); - } - } - - if (type instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) type; - Type[] params = pt.getActualTypeArguments(); - for (Type param : params) { - addTypeToImports(param, importedTypes, genTypePkg); - } - } - } - - public static List createImportLines( - Map> imports) { - List importLines = new ArrayList(); - - for (Map.Entry> entry : imports - .entrySet()) { - String typeName = entry.getKey(); - LinkedHashMap typePkgMap = entry.getValue(); - String typePkg = typePkgMap.keySet().iterator().next(); - importLines.add("import " + typePkg + "." + typeName + SC); - } - return importLines; - } + return; + } + LinkedHashMap packages = importedTypes.get(typeName); + if (packages == null) { + packages = new LinkedHashMap(); + packages.put(typePkg, 1); + importedTypes.put(typeName, packages); + } else { + Integer occurrence = packages.get(typePkg); + if (occurrence == null) { + packages.put(typePkg, 1); + } else { + occurrence++; + packages.put(typePkg, occurrence); + } + } + + if (type instanceof ParameterizedType) { + ParameterizedType pt = (ParameterizedType) type; + Type[] params = pt.getActualTypeArguments(); + for (Type param : params) { + addTypeToImports(param, importedTypes, genTypePkg); + } + } + } + + public static List createImportLines( + Map> imports) { + List importLines = new ArrayList(); + + for (Map.Entry> entry : imports + .entrySet()) { + String typeName = entry.getKey(); + LinkedHashMap typePkgMap = entry.getValue(); + String typePkg = typePkgMap.keySet().iterator().next(); + importLines.add("import " + typePkg + "." + typeName + SC); + } + return importLines; + } } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/yang/abstract-topology@2013-02-08.yang b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/yang/abstract-topology@2013-02-08.yang index 7ed1f99503..8bdf32706b 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/yang/abstract-topology@2013-02-08.yang +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/resources/yang/abstract-topology@2013-02-08.yang @@ -138,4 +138,34 @@ module abstract-topology { } } } -} \ No newline at end of file + + identity crypto-base { + description "crypto-base description"; + } + + identity crypto-alg { + base crypto-base; + description "crypto-alg description"; + } + + grouping target { + container nodes { + leaf source { + type int8; + } + leaf target { + type int16; + } + } + leaf id { + type string; + } + } + + leaf idreftest { + type identityref { + base crypto-alg; + } + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferIdentityObject.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferIdentityObject.java new file mode 100644 index 0000000000..80bed83fdd --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/GeneratedTransferIdentityObject.java @@ -0,0 +1,6 @@ +package org.opendaylight.controller.sal.binding.model.api; + +public interface GeneratedTransferIdentityObject extends + GeneratedTransferObject { + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/WildcardType.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/WildcardType.java new file mode 100644 index 0000000000..ad08c2f4dd --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/WildcardType.java @@ -0,0 +1,5 @@ +package org.opendaylight.controller.sal.binding.model.api; + +public interface WildcardType extends Type { + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTOBuilder.java b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTOBuilder.java index c01425407d..fc3495e184 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTOBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-model-api/src/main/java/org/opendaylight/controller/sal/binding/model/api/type/builder/GeneratedTOBuilder.java @@ -13,9 +13,9 @@ import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject */ public interface GeneratedTOBuilder extends GeneratedTypeBuilder { - + public boolean addExtendsType(final GeneratedTransferObject genTransObj); - + public GeneratedPropertyBuilder addProperty(final String name); public boolean addEqualsIdentity(final GeneratedPropertyBuilder property); @@ -26,4 +26,7 @@ public interface GeneratedTOBuilder extends GeneratedTypeBuilder { @Override public GeneratedTransferObject toInstance(); + + public GeneratedTransferObject toIdentityInstance(); + } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataNodeContainerBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataNodeContainerBuilder.java index 32c7a6d3f1..e64bb02c6d 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataNodeContainerBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataNodeContainerBuilder.java @@ -24,6 +24,8 @@ public interface DataNodeContainerBuilder extends Builder { void addChildNode(DataSchemaNodeBuilder childNode); + Set getGroupings(); + void addGrouping(GroupingBuilder groupingBuilder); void addUsesNode(UsesNodeBuilder usesBuilder); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java index 1c4a4acde4..c295c0eafd 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java @@ -19,9 +19,13 @@ import org.opendaylight.controller.yang.parser.util.RefineHolder; */ public interface UsesNodeBuilder extends Builder { - String getGroupingPathString(); + String getGroupingName(); - SchemaPath getGroupingPath(); + void setGroupingPath(SchemaPath groupingPath); + + SchemaPath getPath(); + + void setPath(SchemaPath path); Set getAugmentations(); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java index e5ba8b17cc..775751a166 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java @@ -68,6 +68,11 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu return childNodes; } + @Override + public Set getGroupings() { + return groupings; + } + @Override public void addGrouping(GroupingBuilder grouping) { groupings.add(grouping); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java index ba9609b4db..ec9c35c1bd 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java @@ -290,6 +290,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder } } + @Override public String getDefault() { return defaultStr; } @@ -298,6 +299,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder this.defaultStr = defaultStr; } + @Override public String getUnits() { return unitsStr; } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java index 67e4c6fb72..fa307972d4 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java @@ -240,6 +240,17 @@ public class ModuleBuilder implements Builder { return typedefs; } + public Set getModuleGroupings() { + final Set groupings = new HashSet(); + for (Map.Entry, GroupingBuilder> entry : addedGroupings + .entrySet()) { + if (entry.getKey().size() == 2) { + groupings.add(entry.getValue()); + } + } + return groupings; + } + public String getName() { return name; } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java index 5b9638eb63..6cbcec1054 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java @@ -103,6 +103,10 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, addedTypedefs.add(type); } + public Set getGroupings() { + return addedGroupings; + } + public void addGrouping(GroupingBuilder grouping) { addedGroupings.add(grouping); } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java index dba747db1d..850938161b 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java @@ -15,7 +15,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.opendaylight.controller.yang.common.QName; import org.opendaylight.controller.yang.model.api.AugmentationSchema; import org.opendaylight.controller.yang.model.api.SchemaNode; import org.opendaylight.controller.yang.model.api.SchemaPath; @@ -27,25 +26,25 @@ import org.opendaylight.controller.yang.parser.util.RefineHolder; public final class UsesNodeBuilderImpl implements UsesNodeBuilder { private boolean isBuilt; - private final UsesNodeImpl instance; + private UsesNodeImpl instance; private final int line; - private final String groupingPathStr; - private final SchemaPath groupingPath; + private SchemaPath schemaPath; + private final String groupingName; + private SchemaPath groupingPath; private boolean augmenting; private final Set addedAugments = new HashSet(); private List refineBuilders = new ArrayList(); private List refines = new ArrayList(); - public UsesNodeBuilderImpl(final String groupingPathStr, final int line) { - this.groupingPathStr = groupingPathStr; - this.groupingPath = parseUsesPath(groupingPathStr); + public UsesNodeBuilderImpl(final String groupingName, final int line) { + this.groupingName = groupingName; this.line = line; - instance = new UsesNodeImpl(groupingPath); } @Override public UsesNode build() { if (!isBuilt) { + instance = new UsesNodeImpl(groupingPath); instance.setAugmenting(augmenting); // AUGMENTATIONS @@ -74,13 +73,23 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder { } @Override - public String getGroupingPathString() { - return groupingPathStr; + public void setGroupingPath(SchemaPath groupingPath) { + this.groupingPath = groupingPath; } @Override - public SchemaPath getGroupingPath() { - return groupingPath; + public SchemaPath getPath() { + return schemaPath; + } + + @Override + public void setPath(SchemaPath path) { + this.schemaPath = path; + } + + @Override + public String getGroupingName() { + return groupingName; } @Override @@ -123,23 +132,6 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder { refines.add(refine); } - private SchemaPath parseUsesPath(final String groupingPathStr) { - final String[] splittedPath = groupingPathStr.split("/"); - final List path = new ArrayList(); - QName name; - for (String pathElement : splittedPath) { - final String[] splittedElement = pathElement.split(":"); - if (splittedElement.length == 1) { - name = new QName(null, null, null, splittedElement[0]); - } else { - name = new QName(null, null, splittedElement[0], - splittedElement[1]); - } - path.add(name); - } - final boolean absolute = groupingPathStr.startsWith("/"); - return new SchemaPath(path, absolute); - } private final class UsesNodeImpl implements UsesNode { private final SchemaPath groupingPath; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java index 4520405bbe..94437170f4 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java @@ -761,15 +761,15 @@ public final class YangParserImpl implements YangModelParser { .getUsesNodes(); for (Map.Entry, UsesNodeBuilder> entry : moduleUses .entrySet()) { - final List key = entry.getKey(); final UsesNodeBuilder usesNode = entry.getValue(); final int line = usesNode.getLine(); - final String groupingName = key.get(key.size() - 1); + GroupingBuilder targetGrouping = getTargetGrouping(usesNode, modules, module); + usesNode.setGroupingPath(targetGrouping.getPath()); for (RefineHolder refine : usesNode.getRefines()) { SchemaNodeBuilder refineTarget = getRefineNodeBuilderCopy( - groupingName, refine, modules, module); + targetGrouping, refine, modules, module); ParserUtils.checkRefine(refineTarget, refine); ParserUtils.refineDefault(refineTarget, refine, line); if (refineTarget instanceof LeafSchemaNodeBuilder) { @@ -805,6 +805,82 @@ public final class YangParserImpl implements YangModelParser { } } + private GroupingBuilder getTargetGrouping( + final UsesNodeBuilder usesBuilder, + final Map> modules, + final ModuleBuilder module) { + final int line = usesBuilder.getLine(); + String groupingString = usesBuilder.getGroupingName(); + String groupingPrefix; + String groupingName; + + if(groupingString.contains(":")) { + String[] splitted = groupingString.split(":"); + if(splitted.length != 2 || groupingString.contains("/")) { + throw new YangParseException(module.getName(), line, "Invalid name of target grouping"); + } + groupingPrefix = splitted[0]; + groupingName = splitted[1]; + } else { + groupingPrefix = module.getPrefix(); + groupingName = groupingString; + } + + ModuleBuilder dependentModule = null; + if(groupingPrefix.equals(module.getPrefix())) { + dependentModule = module; + } else { + dependentModule = findDependentModule(modules, module, groupingPrefix, line); + } + + + List path = usesBuilder.getPath().getPath(); + GroupingBuilder result = null; + Set groupings = dependentModule.getModuleGroupings(); + result = findGrouping(groupings, groupingName); + + if (result == null) { + Builder currentNode = null; + final List currentPath = new ArrayList(); + currentPath.add(dependentModule.getName()); + + for (int i = 0; i < path.size(); i++) { + QName qname = path.get(i); + currentPath.add(qname.getLocalName()); + currentNode = dependentModule.getModuleNode(currentPath); + + if (currentNode instanceof RpcDefinitionBuilder) { + groupings = ((RpcDefinitionBuilder) currentNode).getGroupings(); + } else if (currentNode instanceof DataNodeContainerBuilder) { + groupings = ((DataNodeContainerBuilder) currentNode).getGroupings(); + } else { + groupings = Collections.emptySet(); + } + + result = findGrouping(groupings, groupingName); + if (result != null) { + break; + } + } + } + + if (result != null) { + return result; + } + throw new YangParseException(module.getName(), line, + "Referenced grouping '" + groupingName + "' not found."); + } + + private GroupingBuilder findGrouping(Set groupings, + String name) { + for (GroupingBuilder grouping : groupings) { + if (grouping.getQName().getLocalName().equals(name)) { + return grouping; + } + } + return null; + } + /** * Find original builder of node to refine and return copy of this builder. *

@@ -825,11 +901,11 @@ public final class YangParserImpl implements YangModelParser { * otherwise */ private SchemaNodeBuilder getRefineNodeBuilderCopy( - final String groupingPath, final RefineHolder refine, + final GroupingBuilder targetGrouping, final RefineHolder refine, final Map> modules, final ModuleBuilder module) { Builder result = null; - final Builder lookedUpBuilder = findRefineTargetBuilder(groupingPath, + final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping, refine, modules, module); if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) { result = ParserUtils @@ -876,28 +952,11 @@ public final class YangParserImpl implements YangModelParser { * @return Builder object of refine node if it is present in grouping, null * otherwise */ - private Builder findRefineTargetBuilder(final String groupingPath, + private Builder findRefineTargetBuilder(final GroupingBuilder builder, final RefineHolder refine, final Map> modules, final ModuleBuilder module) { final String refineNodeName = refine.getName(); - final SchemaPath path = ParserUtils.parseUsesPath(groupingPath); - final List builderPath = new ArrayList(); - String prefix = null; - for (QName qname : path.getPath()) { - builderPath.add(qname.getLocalName()); - prefix = qname.getPrefix(); - } - if (prefix == null) { - prefix = module.getPrefix(); - } - - final ModuleBuilder dependentModule = findDependentModule(modules, - module, prefix, refine.getLine()); - builderPath.add(0, dependentModule.getName()); - final GroupingBuilder builder = dependentModule - .getGrouping(builderPath); - Builder result = builder.getChildNode(refineNodeName); if (result == null) { Set grps = builder.getGroupings(); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java index 40a3289745..1c01cd4a82 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java @@ -410,15 +410,15 @@ public final class YangParserListenerImpl extends YangParserBaseListener { GroupingBuilder builder = moduleBuilder.addGrouping(groupQName, actualPath, ctx.getStart().getLine()); moduleBuilder.enterNode(builder); - updatePath("grouping"); updatePath(groupName); + builder.setPath(createActualSchemaPath(actualPath, namespace, revision, + yangModelPrefix)); parseSchemaNodeArgs(ctx, builder); } @Override public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) { String actContainer = actualPath.pop(); - actContainer += "-" + actualPath.pop(); logger.debug("exiting " + actContainer); moduleBuilder.exitNode(); } @@ -495,8 +495,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener { final String groupingPathStr = stringFromNode(ctx); UsesNodeBuilder builder = moduleBuilder.addUsesNode(groupingPathStr, actualPath, ctx.getStart().getLine()); + moduleBuilder.enterNode(builder); updatePath(groupingPathStr); + builder.setPath(createActualSchemaPath(actualPath, namespace, revision, + yangModelPrefix)); } @Override diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java index 8361d47156..d38bc5e7ad 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java @@ -907,7 +907,7 @@ public final class ParserUtils { public static UsesNodeBuilder copyUsesNodeBuilder(UsesNodeBuilder old) { final UsesNodeBuilder copy = new UsesNodeBuilderImpl( - old.getGroupingPathString(), old.getLine()); + old.getGroupingName(), old.getLine()); for (AugmentationSchemaBuilder augment : old.getAugmentations()) { copy.addAugment(augment); } diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/BaseIdentity.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/BaseIdentity.java new file mode 100644 index 0000000000..004287aebc --- /dev/null +++ b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/BaseIdentity.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2013 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.controller.yang.binding; + +public abstract class BaseIdentity { + + protected BaseIdentity() { + } + +} diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/DataNodeIterator.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/DataNodeIterator.java index df111acf08..7c26531f37 100644 --- a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/DataNodeIterator.java +++ b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/DataNodeIterator.java @@ -8,29 +8,30 @@ import java.util.Set; import org.opendaylight.controller.yang.model.api.ContainerSchemaNode; import org.opendaylight.controller.yang.model.api.DataNodeContainer; import org.opendaylight.controller.yang.model.api.DataSchemaNode; +import org.opendaylight.controller.yang.model.api.GroupingDefinition; import org.opendaylight.controller.yang.model.api.LeafListSchemaNode; import org.opendaylight.controller.yang.model.api.LeafSchemaNode; import org.opendaylight.controller.yang.model.api.ListSchemaNode; public class DataNodeIterator implements Iterator { - + private final DataNodeContainer container; private List allLists; private List allContainers; private List allLeafs; private List allLeafLists; private List allChilds; - + public DataNodeIterator(final DataNodeContainer container) { if (container == null) { throw new IllegalArgumentException("Data Node Container MUST be specified and cannot be NULL!"); } - + init(); this.container = container; traverse(this.container); } - + private void init() { this.allContainers = new ArrayList(); this.allLists = new ArrayList(); @@ -38,28 +39,28 @@ public class DataNodeIterator implements Iterator { this.allLeafLists = new ArrayList(); this.allChilds = new ArrayList(); } - + public List allContainers() { return allContainers; } - + public List allLists() { return allLists; } - + public List allLeafs() { return allLeafs; } - + public List allLeafLists() { return allLeafLists; } - + private void traverse(final DataNodeContainer dataNode) { if (dataNode == null) { return; } - + final Set childs = dataNode.getChildNodes(); if (childs != null) { for (DataSchemaNode childNode : childs) { @@ -83,15 +84,21 @@ public class DataNodeIterator implements Iterator { allLeafLists.add(leafList); } } - return; + } + + final Set groupings = dataNode.getGroupings(); + if(groupings != null) { + for(GroupingDefinition grouping : groupings) { + traverse(grouping); + } } } - + @Override public boolean hasNext() { if (container.getChildNodes() != null) { Set childs = container.getChildNodes(); - + if ((childs != null) && !childs.isEmpty()) { return childs.iterator().hasNext(); } -- 2.36.6