Implemented build of default instance for union types. 31/3531/9
authorMartin Vitez <mvitez@cisco.com>
Fri, 6 Dec 2013 13:13:58 +0000 (14:13 +0100)
committerMartin Vitez <mvitez@cisco.com>
Fri, 13 Dec 2013 10:29:31 +0000 (11:29 +0100)
For each union type class <union-name>Builder will be generated to folder specified in persistentSourcesDir parameter in build configuration of yang-maven-plugin.
If parameter is not specified, this builder will be generated to src/main/java by default. Each such builder will contain getDefaultInstance method, which accepts String parameter.
This method will be called from union class constuctor with char[] argument and creates default instance for given union type.

Implemented method getParamNameFromType to create param name from given TypeDefinition.
Updated tests.

Change-Id: I78ebe37acd732fd70c6fe152c18c6c91224cb5e4
Signed-off-by: Martin Vitez <mvitez@cisco.com>
24 files changed:
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/BitAndUnionTOEnclosingTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ExtendedTypedefTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/TypeProviderIntegrationTest.java
code-generator/binding-generator-impl/src/test/resources/type-provider/test.yang
code-generator/binding-generator-spi/src/main/java/org/opendaylight/yangtools/sal/binding/generator/spi/TypeProvider.java
code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/generated/type/builder/GeneratedTOBuilderImpl.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorJavaFile.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/TOGenerator.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/UnionBuilderTemplate.xtend [new file with mode: 0644]
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/UnionTemplate.xtend
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java
code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/GeneratedTransferObject.java
code-generator/binding-model-api/src/main/java/org/opendaylight/yangtools/sal/binding/model/api/type/builder/GeneratedTOBuilder.java
code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/BaseYangTypes.java
code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java
code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/maven/sal/api/gen/plugin/CodeGeneratorImpl.java
model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/HostBuilder.java [new file with mode: 0644]
model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/IpAddressBuilder.java [new file with mode: 0644]
model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/IpPrefixBuilder.java [new file with mode: 0644]

index b284ead5b19fb31c72a36550f4ccce4fa5965111..7c3ba6b1e6d84eaf1b74714bbf7a22573bc55230 100644 (file)
@@ -75,9 +75,13 @@ import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder
 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl
+
 import org.opendaylight.yangtools.yang.common.QName\rimport org.opendaylight.yangtools.yang.binding.BindingMapping
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase
 
+import org.opendaylight.yangtools.yang.common.QName\rimport com.google.common.collect.Sets
+
+
 public class BindingGeneratorImpl implements BindingGenerator {
 
     private final Map<Module, ModuleContext> genCtx = new HashMap()
@@ -185,10 +189,12 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         val List<Type> filteredGenTypes = new ArrayList();
         for (Module m : modules) {
-            filteredGenTypes.addAll(genCtx.get(m).generatedTypes);
-
-        }
-        //genCtx.clear;
+            filteredGenTypes.addAll(genCtx.get(m).generatedTypes);\r
+            val Set<Type> additionalTypes = (typeProvider as TypeProviderImpl).additionalTypes.get(m)\r
+            if (additionalTypes != null) {\r
+                filteredGenTypes.addAll(additionalTypes)\r
+            }
+        }\r
 
         return filteredGenTypes;
     }
@@ -238,7 +244,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 }
             }
         }
-    }
+    }\r
 \r
     private def GeneratedTypeBuilder processDataSchemaNode(Module module, String basePackageName,
         GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, DataSchemaNode node) {
@@ -1342,6 +1348,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 val TypeDefinition<?> typeDef = leaf.type;
 
                 var Type returnType = null;
+                var GeneratedTOBuilder genTOBuilder;
                 if (typeDef instanceof EnumTypeDefinition) {
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
                     val enumTypeDef = typeDef as EnumTypeDefinition;
@@ -1352,17 +1359,17 @@ public class BindingGeneratorImpl implements BindingGenerator {
                     }
                     (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType);
                 } else if (typeDef instanceof UnionType) {
-                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder,  leaf, parentModule);
-                    if (genTOBuilder !== null) {
-                        returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
+                    genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);\r
+                    if (genTOBuilder !== null) {\r
+                        returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)\r
                     }
                 } else if (typeDef instanceof BitsTypeDefinition) {
-                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder,  leaf, parentModule);
-                    if (genTOBuilder !== null) {
-                        returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
+                    genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);\r
+                    if (genTOBuilder !== null) {\r
+                        returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
                     }
-                } else {\r
-                    val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);\r
+                } else {
+                    val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions);
                 }
                 if (returnType !== null) {
@@ -1515,10 +1522,12 @@ public class BindingGeneratorImpl implements BindingGenerator {
                     returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);\r
                     (typeProvider as TypeProviderImpl).putReferencedType(node.path, returnType);\r
                 } else if (typeDef instanceof UnionType) {\r
-                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder,  node, parentModule);\r
-                    returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
+                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);\r
+                    if (genTOBuilder !== null) {\r
+                        returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)\r
+                    }
                 } else if (typeDef instanceof BitsTypeDefinition) {\r
-                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder,  node, parentModule);\r
+                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);\r
                     returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
                 } else {\r
                     val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);\r
@@ -1532,6 +1541,33 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
         return false;
     }
+\r
+    private def Type createReturnTypeForUnion(GeneratedTOBuilder genTOBuilder, TypeDefinition<?> typeDef,
+        GeneratedTypeBuilder typeBuilder, Module parentModule) {
+        val Type returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
+        genTOBuilder.setTypedef(true);
+        genTOBuilder.setIsUnion(true);
+        (typeProvider as TypeProviderImpl).addUnitsToGenTO(genTOBuilder, typeDef.getUnits());
+
+        // union builder\r
+        val GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(typeBuilder.getPackageName(),
+            genTOBuilder.getName() + "Builder");
+        unionBuilder.setIsUnionBuilder(true);
+        val MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
+        method.setReturnType(returnType);
+        method.addParameter(Types.STRING, "defaultValue");
+        method.setAccessModifier(AccessModifier.PUBLIC);
+        method.setStatic(true);
+
+        val Set<Type> types = (typeProvider as TypeProviderImpl).additionalTypes.get(parentModule);
+        if (types == null) {
+            (typeProvider as TypeProviderImpl).additionalTypes.put(parentModule,
+                Sets.newHashSet(unionBuilder.toInstance))
+        } else {
+            types.add(unionBuilder.toInstance)
+        }
+        return returnType
+    }\r
 
     private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) {
         return addDefaultInterfaceDefinition(packageName, schemaNode, null);
@@ -1827,11 +1863,27 @@ public class BindingGeneratorImpl implements BindingGenerator {
         val classNameFromLeaf = BindingMapping.getClassName(leaf.QName);
         val List<GeneratedTOBuilder> genTOBuilders = new ArrayList();
         val packageName = typeBuilder.fullyQualifiedName;
-        if (typeDef instanceof UnionTypeDefinition) {
-            genTOBuilders.addAll(
-                (typeProvider as TypeProviderImpl).
-                    provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition),
-                        classNameFromLeaf, leaf));
+        if (typeDef instanceof UnionTypeDefinition) {\r
+            val List<GeneratedTOBuilder> types = (typeProvider as TypeProviderImpl).\r
+                    provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition),\r
+                        classNameFromLeaf, leaf); 
+            genTOBuilders.addAll(types);\r
+                        \r
+            \r
+        var GeneratedTOBuilder resultTOBuilder = null;\r
+        if (!types.isEmpty()) {\r
+            resultTOBuilder = types.remove(0);\r
+            for (GeneratedTOBuilder genTOBuilder : types) {\r
+                resultTOBuilder.addEnclosingTransferObject(genTOBuilder);\r
+            }\r
+        }\r
+\r
+        val GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");\r
+        genPropBuilder.setReturnType(Types.primitiveType("char[]", null));\r
+        resultTOBuilder.addEqualsIdentity(genPropBuilder);\r
+        resultTOBuilder.addHashIdentity(genPropBuilder);\r
+        resultTOBuilder.addToStringProperty(genPropBuilder);\r
+
         } else if (typeDef instanceof BitsTypeDefinition) {
             genTOBuilders.add(
                 ((typeProvider as TypeProviderImpl) ).
index 83eb4155c9283f50cf96c410c17a1f1ec50a9db3..9908fc4cf45b0c252b1061f3c832454588ba4524 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.yangtools.sal.binding.generator.impl;
 
-import static org.junit.Assert.*;
-
-import static org.opendaylight.yangtools.sal.binding.generator.impl.SupportTestUtil.containsMethods;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.opendaylight.yangtools.sal.binding.generator.impl.SupportTestUtil.containsAttributes;
+import static org.opendaylight.yangtools.sal.binding.generator.impl.SupportTestUtil.containsMethods;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -93,7 +93,7 @@ public class BitAndUnionTOEnclosingTest {
                 "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev130626.ParentContainer",
                 lfLeaf.getPackageName());
 
-        assertEquals("Lf generated TO has incorrect number of properties", 2, lfLeaf.getProperties().size());
+        assertEquals("Lf generated TO has incorrect number of properties", 3, lfLeaf.getProperties().size());
         containsAttributes(lfLeaf, true, true, true, new NameTypePattern("string", "String"));
         containsAttributes(lfLeaf, true, false, true, new NameTypePattern("lf1", "Lf1"));
 
@@ -146,7 +146,7 @@ public class BitAndUnionTOEnclosingTest {
         assertEquals("TypeUnion has incorrect package name.",
                 "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev130626", typeUnionTypedef.getPackageName());
 
-        assertEquals("TypeUnion generated TO has incorrect number of properties", 2, typeUnionTypedef.getProperties()
+        assertEquals("TypeUnion generated TO has incorrect number of properties", 3, typeUnionTypedef.getProperties()
                 .size());
         containsAttributes(typeUnionTypedef, true, true, true, new NameTypePattern("string", "String"));
         containsAttributes(typeUnionTypedef, true, false, true, new NameTypePattern("typeUnion1", "TypeUnion1"));
@@ -177,7 +177,7 @@ public class BitAndUnionTOEnclosingTest {
                 "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev130626", typeUnion1.getPackageName());
 
         assertEquals("TypeUnion1 generated TO has incorrect number of properties", 4, typeUnion1.getProperties().size());
-       
+
         containsAttributes(typeUnion1, true, true, true, new NameTypePattern("uint32", "Long"));
         containsAttributes(typeUnion1, true, true, true, new NameTypePattern("int8", "Byte"));
         containsAttributes(typeUnion1, true, true, true, new NameTypePattern("string", "String"));
index a08a9bbf3ed42efcc62be4a2a04f0e54539a2ce6..9bdf9158e157547d8eb8522ef1caa7c07435f7ce 100644 (file)
@@ -109,7 +109,7 @@ public class ExtendedTypedefTest {
         extendTO = extendedTypedefUnion.getSuperType();\r
         assertEquals("Incorrect extension fo ExtendedTypedefUnion.", "UnionTypedef", extendTO.getName());\r
         assertNull("UnionTypedef shouldn't be extended", extendTO.getSuperType());\r
-        assertEquals("Incorrect number of properties for UnionTypedef.", 4, extendTO.getProperties().size());\r
+        assertEquals("Incorrect number of properties for UnionTypedef.", 5, extendTO.getProperties().size());\r
 \r
         GeneratedProperty simpleTypedef4Property = null;\r
         GeneratedProperty simpleTypedef1Property = null;\r
index 7c235f3fb176983c89ea1505e295238ba269c69c..913d0b6a2d797212e9da126ce3dcbfacd97e0e7b 100644 (file)
@@ -51,7 +51,7 @@ public class GeneratedTypesTest {
         final List<Type> genTypes = bindingGen.generateTypes(context);\r
 \r
         assertNotNull(genTypes);\r
-        assertEquals(26, genTypes.size());\r
+        assertEquals(29, genTypes.size());\r
     }\r
 \r
     @Test\r
@@ -83,7 +83,7 @@ public class GeneratedTypesTest {
         final BindingGenerator bindingGen = new BindingGeneratorImpl();\r
         final List<Type> genTypes = bindingGen.generateTypes(context);\r
 \r
-        assertEquals(51, genTypes.size());\r
+        assertEquals(54, genTypes.size());\r
         assertNotNull(genTypes);\r
 \r
         GeneratedTransferObject gtIfcKey = null;\r
index d007f892656915366430cac7cb5ef636644c9182..f9b7fb8bbb5fb0955fd93b202e502b9c40c0c26d 100644 (file)
@@ -13,17 +13,11 @@ import static org.junit.Assert.assertNotNull;
 import java.io.File;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.*;
 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.*;
 import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 
@@ -243,6 +237,61 @@ public class TypeProviderIntegrationTest {
         assertEquals(exp, actual);
     }
 
+    @Test
+    public void testGetTypeDefaultConstructionUnion() throws ParseException {
+        LeafSchemaNode leaf = (LeafSchemaNode) m.getDataChildByName("leaf-union");
+        String actual = provider.getTypeDefaultConstruction(leaf);
+        String expected = "new " + PKG + "TestData.LeafUnion(\"111\".toCharArray())";
+        assertEquals(expected, actual);
+
+        leaf = (LeafSchemaNode) m.getDataChildByName("ext-union");
+        actual = provider.getTypeDefaultConstruction(leaf);
+        expected = "new " + PKG + "MyUnion(\"111\".toCharArray())";
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testGetTypeDefaultConstructionUnionNested() throws ParseException {
+        ContainerSchemaNode c1 = (ContainerSchemaNode)m.getDataChildByName("c1");
+        ContainerSchemaNode c2 = (ContainerSchemaNode)c1.getDataChildByName("c2");
+        ContainerSchemaNode c3 = (ContainerSchemaNode)c2.getDataChildByName("c3");
+        LeafSchemaNode leaf = (LeafSchemaNode) c3.getDataChildByName("id");
+
+        String actual = provider.getTypeDefaultConstruction(leaf);
+        String expected = "new " + PKG + "NestedUnion(\"111\".toCharArray())";
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    public void testGetParamNameFromType() throws ParseException {
+        m = context.findModuleByName("ietf-inet-types", new SimpleDateFormat("yyyy-MM-dd").parse("2010-09-24"));
+        Set<TypeDefinition<?>> types = m.getTypeDefinitions();
+        TypeDefinition<?> ipv4 = null;
+        TypeDefinition<?> ipv6 = null;
+        TypeDefinition<?> ipv4Pref = null;
+        TypeDefinition<?> ipv6Pref = null;
+        for (TypeDefinition<?> type : types) {
+            if ("ipv4-address".equals(type.getQName().getLocalName())) {
+                ipv4 = type;
+            } else if ("ipv6-address".equals(type.getQName().getLocalName())) {
+                ipv6 = type;
+            } else if ("ipv4-prefix".equals(type.getQName().getLocalName())) {
+                ipv4Pref = type;
+            } else if ("ipv6-prefix".equals(type.getQName().getLocalName())) {
+                ipv6Pref = type;
+            }
+        }
+
+        assertNotNull(ipv4);
+        assertNotNull(ipv6);
+        assertNotNull(ipv4Pref);
+        assertNotNull(ipv6Pref);
+        assertEquals("ipv4Address", provider.getParamNameFromType(ipv4));
+        assertEquals("ipv6Address", provider.getParamNameFromType(ipv6));
+        assertEquals("ipv4Prefix", provider.getParamNameFromType(ipv4Pref));
+        assertEquals("ipv6Prefix", provider.getParamNameFromType(ipv6Pref));
+    }
+
     private static SchemaContext resolveSchemaContextFromFiles(final String... yangFiles) {
         final YangModelParser parser = new YangParserImpl();
 
index c47f00cde011d0f80e527153914faf8b2d3fd2d0..d17b86ea83e8c15a8c60c63c5fd8a8d335dd3b67 100644 (file)
@@ -351,6 +351,43 @@ module test {
         default "11111";
     }
 
+    // uint64
+    typedef my-union {
+        type union {
+            type string;
+            type my-binary;
+        }
+    }
+
+    leaf ext-union {
+        type my-union;
+        default "111";
+    }
+
+    leaf leaf-union {
+        type union {
+            type string;
+            type int8;
+        }
+        default "111";
+    }
+
+    container c1 {
+        container c2 {
+            typedef nested-union {
+                type union {
+                    type string;
+                    type int16;
+                }
+            }
+            container c3 {
+                leaf id {
+                    type nested-union;
+                    default "111";
+                }
+            }
+        }
+    }
 
 
     list links {
index bf3a188f36ec93daa3cdd892c5d43ff66dd87ee4..e2d6b71241234ba7e233ce24398d7f240dd44328 100644 (file)
@@ -47,4 +47,7 @@ public interface TypeProvider {
     String getTypeDefaultConstruction(LeafSchemaNode node);\r
 \r
     String getConstructorPropertyName(SchemaNode node);\r
+\r
+    String getParamNameFromType(TypeDefinition<?> type);\r
+\r
 }\r
index 9902a5cb0b2b89963218ec757e800e248f92791b..202b16b2f207812dcb6aed5685e987a515b8018f 100644 (file)
@@ -12,7 +12,9 @@ import java.util.List;
 \r
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;\r
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;\r
+import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType;\r
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions;\r
+import org.opendaylight.yangtools.sal.binding.model.api.Type;\r
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;\r
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;\r
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder;\r
@@ -21,12 +23,12 @@ public final class GeneratedTOBuilderImpl extends AbstractGeneratedTypeBuilder<G
         GeneratedTOBuilder {\r
 \r
     private GeneratedTransferObject extendsType;\r
-    private final List<GeneratedPropertyBuilder> properties = new ArrayList<>();\r
     private final List<GeneratedPropertyBuilder> equalsProperties = new ArrayList<>();\r
     private final List<GeneratedPropertyBuilder> hashProperties = new ArrayList<>();\r
     private final List<GeneratedPropertyBuilder> toStringProperties = new ArrayList<>();\r
     private boolean isTypedef = false;\r
     private boolean isUnionType = false;\r
+    private boolean isUnionTypeBuilder = false;\r
     private Restrictions restrictions;\r
     private GeneratedPropertyBuilder SUID;\r
 \r
@@ -116,8 +118,6 @@ public final class GeneratedTOBuilderImpl extends AbstractGeneratedTypeBuilder<G
         builder.append(getConstants());\r
         builder.append(", enumerations=");\r
         builder.append(getEnumerations());\r
-        builder.append(", properties=");\r
-        builder.append(properties);\r
         builder.append(", equalsProperties=");\r
         builder.append(equalsProperties);\r
         builder.append(", hashCodeProperties=");\r
@@ -142,6 +142,11 @@ public final class GeneratedTOBuilderImpl extends AbstractGeneratedTypeBuilder<G
         this.isUnionType = isUnion;\r
     }\r
 \r
+    @Override\r
+    public void setIsUnionBuilder(boolean isUnionTypeBuilder) {\r
+        this.isUnionTypeBuilder = isUnionTypeBuilder;\r
+    }\r
+\r
     private static final class GeneratedTransferObjectImpl extends AbstractGeneratedType implements\r
             GeneratedTransferObject {\r
 \r
@@ -151,6 +156,7 @@ public final class GeneratedTOBuilderImpl extends AbstractGeneratedTypeBuilder<G
         private final GeneratedTransferObject extendsType;\r
         private final boolean isTypedef;\r
         private final boolean isUnionType;\r
+        private final boolean isUnionTypeBuilder;\r
         private final Restrictions restrictions;\r
         private final GeneratedProperty SUID;\r
 \r
@@ -162,6 +168,7 @@ public final class GeneratedTOBuilderImpl extends AbstractGeneratedTypeBuilder<G
             this.stringProperties = toUnmodifiableProperties(builder.toStringProperties);\r
             this.isTypedef = builder.isTypedef;\r
             this.isUnionType = builder.isUnionType;\r
+            this.isUnionTypeBuilder = builder.isUnionTypeBuilder;\r
             this.restrictions = builder.restrictions;\r
             if (builder.SUID == null) {\r
                 this.SUID = null;\r
@@ -180,6 +187,11 @@ public final class GeneratedTOBuilderImpl extends AbstractGeneratedTypeBuilder<G
             return isUnionType;\r
         }\r
 \r
+        @Override\r
+        public boolean isUnionTypeBuilder() {\r
+            return isUnionTypeBuilder;\r
+        }\r
+\r
         @Override\r
         public GeneratedTransferObject getSuperType() {\r
             return extendsType;\r
@@ -212,6 +224,9 @@ public final class GeneratedTOBuilderImpl extends AbstractGeneratedTypeBuilder<G
 \r
         @Override\r
         public String toString() {\r
+            if(isTypedef) {\r
+                return serializeTypedef(this);\r
+            }\r
             StringBuilder builder = new StringBuilder();\r
             builder.append("GeneratedTransferObject [packageName=");\r
             builder.append(getPackageName());\r
@@ -244,5 +259,28 @@ public final class GeneratedTOBuilderImpl extends AbstractGeneratedTypeBuilder<G
             builder.append("]");\r
             return builder.toString();\r
         }\r
+\r
+        public String serializeTypedef(Type type) {\r
+            if (type instanceof ParameterizedType) {\r
+                ParameterizedType parameterizedType = (ParameterizedType) type;\r
+                StringBuffer sb = new StringBuffer();\r
+                sb.append(parameterizedType.getRawType().getFullyQualifiedName());\r
+                sb.append("<");\r
+                boolean first = true;\r
+                for (Type parameter : parameterizedType.getActualTypeArguments()) {\r
+                    if (first) {\r
+                        first = false;\r
+                    } else {\r
+                        sb.append(",");\r
+                    }\r
+                    sb.append(serializeTypedef(parameter));\r
+                }\r
+                sb.append(">");\r
+                return sb.toString();\r
+            } else {\r
+                return type.getFullyQualifiedName();\r
+            }\r
+        }\r
+\r
     }\r
 }\r
index a6591fce91c014e8bf1c2b851227ef5163c8c3c3..b9118ac0f513d7cc6e5dfc4f42481e4a1ee0d1b8 100644 (file)
@@ -322,4 +322,19 @@ abstract class BaseTemplate {
         return "\"" + obj.toString + "\"";
     }
 
+    /**
+     * Template method which generates method parameters with their types from <code>parameters</code>.
+     * 
+     * @param parameters
+     * list of parameter instances which are transformed to the method parameters
+     * @return string with the list of the method parameters with their types in JAVA format
+     */
+    def protected generateParameters(List<MethodSignature.Parameter> parameters) '''«
+        IF !parameters.empty»«
+            FOR parameter : parameters SEPARATOR ", "»«
+                parameter.type.importedName» Â«parameter.name»«
+            ENDFOR»«
+        ENDIF
+    Â»'''
+
 }
index e2d3fb28e0788293ff208a65599d697a286cbfb4..d6556157562fa89f1a5d7d939e17dac26f53fab3 100644 (file)
@@ -18,6 +18,7 @@ import java.util.List;
 import java.util.Set;
 
 import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator;
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -87,18 +88,33 @@ public final class GeneratorJavaFile {
      * Generates list of files with JAVA source code. Only the suitable code
      * generator is used to generate the source code for the concrete type.
      *
-     * @param parentDirectory
+     * @param generatedSourcesDirectory
      *            directory to which the output source codes should be generated
      * @return list of output files
      * @throws IOException
      *             if the error during writing to the file occurs
      */
-    public List<File> generateToFile(final File parentDirectory) throws IOException {
+    public List<File> generateToFile(final File generatedSourcesDirectory) throws IOException {
+        return generateToFile(generatedSourcesDirectory, generatedSourcesDirectory);
+    }
+
+    public List<File> generateToFile(final File generatedSourcesDirectory, final File persistenSourcesDirectory)
+            throws IOException {
         final List<File> result = new ArrayList<>();
         for (Type type : types) {
             if (type != null) {
                 for (CodeGenerator generator : generators) {
-                    File generatedJavaFile = generateTypeToJavaFile(parentDirectory, type, generator);
+                    File generatedJavaFile = null;
+                    if (type instanceof GeneratedTransferObject
+                            && ((GeneratedTransferObject) type).isUnionTypeBuilder()) {
+                        File packageDir = packageToDirectory(persistenSourcesDirectory, type.getPackageName());
+                        File file = new File(packageDir, generator.getUnitName(type) + ".java");
+                        if (!file.exists()) {
+                            generatedJavaFile = generateTypeToJavaFile(persistenSourcesDirectory, type, generator);
+                        }
+                    } else {
+                        generatedJavaFile = generateTypeToJavaFile(generatedSourcesDirectory, type, generator);
+                    }
                     if (generatedJavaFile != null) {
                         result.add(generatedJavaFile);
                     }
index ad6456fa20cbc8b4ff36ddb1f9020222596cbd4e..e90b99c136bba015047d8ca290e2c5d88c530da1 100644 (file)
@@ -120,6 +120,7 @@ class InterfaceTemplate extends BaseTemplate {
          Â«ENDFOR»\r
      Â« ENDIF»\r
      '''\r
+\r
     /**\r
      * Template method which generates inner classes inside this interface.\r
      * \r
@@ -129,10 +130,16 @@ class InterfaceTemplate extends BaseTemplate {
         Â«IF !enclosedGeneratedTypes.empty»\r
             Â«FOR innerClass : enclosedGeneratedTypes SEPARATOR "\n"»\r
                 Â«IF (innerClass instanceof GeneratedTransferObject)»\r
-                    Â«val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)»\r
-                    Â«classTemplate.generateAsInnerClass»\r
-                    Â«this.importMap.putAll(classTemplate.importMap)»\r
-                    \r
+                    Â«IF (innerClass as GeneratedTransferObject).unionType»\r
+                        Â«val unionTemplate = new UnionTemplate(innerClass as GeneratedTransferObject)»\r
+                        Â«unionTemplate.generateAsInnerClass»\r
+                        Â«this.importMap.putAll(unionTemplate.importMap)»\r
+                    Â«ELSE»\r
+                        Â«val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)»\r
+                        Â«classTemplate.generateAsInnerClass»\r
+                        Â«this.importMap.putAll(classTemplate.importMap)»\r
+                    Â«ENDIF»\r
+\r
                 Â«ENDIF»\r
             Â«ENDFOR»\r
         Â«ENDIF»\r
@@ -181,22 +188,6 @@ class InterfaceTemplate extends BaseTemplate {
             Â«ENDFOR»\r
         Â«ENDIF»\r
     '''\r
-    \r
-    /**\r
-     * Template method which generates method parameters with their types from <code>parameters</code>.\r
-     * \r
-     * @param parameters\r
-     * list of parameter instances which are transformed to the method parameters\r
-     * @return string with the list of the method parameters with their types in JAVA format\r
-     */\r
-    def private generateParameters(List<MethodSignature.Parameter> parameters) '''«\r
-        IF !parameters.empty»«\r
-            FOR parameter : parameters SEPARATOR ", "»«\r
-                parameter.type.importedName» Â«parameter.name»«\r
-            ENDFOR»«\r
-        ENDIF\r
-    Â»'''\r
 \r
-    \r
 }\r
 \r
index 994fd79031caadca7f2e1a4942004ede3aa0098e..7cd57f6a82515bba64d5e6f883e42588783124d7 100644 (file)
@@ -12,11 +12,11 @@ import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;\r
 \r
 /**\r
- * \r
+ *\r
  * Transformator of the data from the virtual form to JAVA source code. The\r
  * result source code represents JAVA class. For generating of the source code\r
  * is used the template written in XTEND language.\r
- * \r
+ *\r
  */\r
 public final class TOGenerator implements CodeGenerator {\r
 \r
@@ -32,6 +32,9 @@ public final class TOGenerator implements CodeGenerator {
             if(genTO.isUnionType()) {\r
                 final UnionTemplate template = new UnionTemplate(genTO);\r
                 return template.generate();\r
+            } else if (genTO.isUnionTypeBuilder()) {\r
+                final UnionBuilderTemplate template = new UnionBuilderTemplate(genTO);\r
+                return template.generate();\r
             } else {\r
                 final ClassTemplate template = new ClassTemplate(genTO);\r
                 return template.generate();\r
diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/UnionBuilderTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/UnionBuilderTemplate.xtend
new file mode 100644 (file)
index 0000000..50eb0b6
--- /dev/null
@@ -0,0 +1,47 @@
+package org.opendaylight.yangtools.sal.java.api.generator
+
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
+import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier
+
+/**\r
+ * Template for generating JAVA class.\r
+ */
+class UnionBuilderTemplate extends ClassTemplate {
+
+    /**\r
+     * Creates instance of this class with concrete <code>genType</code>.\r
+     *\r
+     * @param genType generated transfer object which will be transformed to JAVA class source code\r
+     */
+    new(GeneratedTransferObject genType) {
+        super(genType)
+    }
+
+    def override body() '''
+        Â«type.comment.asJavadoc»\r
+        public class Â«type.name» {\r
+\r
+            Â«generateMethods»\r
+\r
+        }\r
+    '''
+
+    def private generateMethods() '''
+        Â«FOR method : genTO.methodDefinitions»
+            Â«method.accessModifier.accessModifier»«IF method.static»static«ENDIF»«IF method.final» final«ENDIF» Â«method.
+            returnType.importedName» Â«method.name»(«method.parameters.generateParameters») {\r
+                return null;\r
+            }\r
+        Â«ENDFOR»
+    '''
+
+    def private String getAccessModifier(AccessModifier modifier) {
+        switch (modifier) {
+            case AccessModifier.PUBLIC: return "public "
+            case AccessModifier.PROTECTED: return "protected "
+            case AccessModifier.PRIVATE: return "private "
+            default: return ""
+        }
+    }
+
+}
index 639a8f2635dba44375f2c1698327ce16da58d690..ef4a4b8c529b50889647c36e1c54be3bb88f1533 100644 (file)
@@ -1,57 +1,90 @@
-package org.opendaylight.yangtools.sal.java.api.generator\r
-\r
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject\r
-\r
-\r
-/**\r
- * Template for generating JAVA class. \r
- */\r
-class UnionTemplate extends ClassTemplate {\r
-\r
-\r
-    \r
-    /**\r
-     * Creates instance of this class with concrete <code>genType</code>.\r
-     * \r
-     * @param genType generated transfer object which will be transformed to JAVA class source code\r
-     */\r
-    new(GeneratedTransferObject genType) {\r
-        super(genType)\r
-    }\r
-    \r
-\r
-    \r
-    \r
-    override constructors() '''\r
-    Â«unionConstructorsParentProperties»\r
-    Â«unionConstructors»\r
-    Â«IF !allProperties.empty»\r
-    Â«copyConstructor»\r
-    Â«ENDIF»\r
-    Â«IF properties.empty && !parentProperties.empty Â»\r
-        Â«parentConstructor»\r
-    Â«ENDIF»\r
-    '''\r
-    \r
-\r
-     def unionConstructors() '''\r
-        Â«FOR property : finalProperties SEPARATOR "\n"»\r
-                Â«val propertyAndTopParentProperties = parentProperties + #[property]»\r
-                public Â«type.name»(«propertyAndTopParentProperties.asArgumentsDeclaration») {\r
-                    super(«parentProperties.asArguments»);\r
-                    this.«property.fieldName» = Â«property.fieldName»;\r
-                    Â«FOR other : finalProperties»\r
-                    Â«IF property != other»this.«other.fieldName» = null;«ENDIF»\r
-                    Â«ENDFOR»\r
-                }\r
-        Â«ENDFOR»\r
-     ''' \r
-\r
-     def unionConstructorsParentProperties() '''\r
-        Â«FOR property : parentProperties SEPARATOR "\n"»\r
-            public Â«type.name»(«property.returnType.importedName» Â«property.fieldName») {\r
-                super(«property.fieldName»);\r
-            }\r
-        Â«ENDFOR»\r
-     ''' \r
-}\r
+package org.opendaylight.yangtools.sal.java.api.generator
+
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
+import java.beans.ConstructorProperties
+
+/**
+ * Template for generating JAVA class. 
+ */
+class UnionTemplate extends ClassTemplate {
+
+    /**
+     * Creates instance of this class with concrete <code>genType</code>.
+     * 
+     * @param genType generated transfer object which will be transformed to JAVA class source code
+     */
+    new(GeneratedTransferObject genType) {
+        super(genType)
+    }
+
+    override constructors() '''
+        Â«unionConstructorsParentProperties»
+        Â«unionConstructors»
+        Â«IF !allProperties.empty»
+            Â«copyConstructor»
+        Â«ENDIF»
+        Â«IF properties.empty && !parentProperties.empty»
+            Â«parentConstructor»
+        Â«ENDIF»
+    '''
+
+    private def unionConstructors() '''
+        Â«FOR property : finalProperties SEPARATOR "\n"»
+            Â«val isCharArray = "char[]".equals(property.returnType.name)»
+            Â«IF isCharArray»
+                /**
+                 * Constructor provided only for using in JMX. Don't use it for
+                 * construction new object of this union type. 
+                 */
+                @«ConstructorProperties.importedName»("«property.name»")
+                public Â«type.name»(«property.returnType.importedName» Â«property.fieldName») {
+                    Â«String.importedName» defVal = new Â«String.importedName»(«property.fieldName»);
+                    Â«type.name» defInst = Â«type.name»Builder.getDefaultInstance(defVal);
+                    Â«FOR other : finalProperties»
+                        Â«IF other.name.equals("value")»
+                            this.«other.fieldName» = Â«other.fieldName»;
+                        Â«ELSE»
+                            this.«other.fieldName» = defInst.«other.fieldName»;
+                        Â«ENDIF»
+                    Â«ENDFOR»
+                }
+            Â«ELSE»
+                Â«val propertyAndTopParentProperties = parentProperties + #[property]»
+                public Â«type.name»(«propertyAndTopParentProperties.asArgumentsDeclaration») {
+                    super(«parentProperties.asArguments»);
+                    this.«property.fieldName» = Â«property.fieldName»;
+                    Â«FOR other : finalProperties»
+                        Â«IF property != other»this.«other.fieldName» = null;«ENDIF»
+                    Â«ENDFOR»
+                }
+            Â«ENDIF»
+        Â«ENDFOR»
+    '''
+
+    private def unionConstructorsParentProperties() '''
+        Â«FOR property : parentProperties SEPARATOR "\n"»
+            public Â«type.name»(«property.returnType.importedName» Â«property.fieldName») {
+                super(«property.fieldName»);
+            }
+        Â«ENDFOR»
+    '''
+
+    override protected copyConstructor() '''
+        /**
+         * Creates a copy from Source Object.
+         *
+         * @param source Source object
+         */
+        public Â«type.name»(«type.name» source) {
+            Â«IF !parentProperties.empty»
+                super(source);
+            Â«ENDIF»
+            Â«IF !properties.empty»
+                Â«FOR p : properties»
+                    this.«p.fieldName» = source.«p.fieldName»;
+                Â«ENDFOR»
+            Â«ENDIF»
+        }
+    '''
+
+}
index 0a67eb92671ce2488db3070b2b6d6fe7a3168666..579b0978a3a3e436119c9562a3ef6c99fc7a5d48 100644 (file)
@@ -374,11 +374,12 @@ public class CompilationTest extends BaseCompilationTest {
         generator.generateToFile(sourcesOutputDir);
 
         File parent = new File(sourcesOutputDir, NS_TEST);
-        assertFilesCount(parent, 4);
         assertTrue(new File(parent, "TestData.java").exists());
         assertTrue(new File(parent, "Nodes.java").exists());
         assertTrue(new File(parent, "NodesBuilder.java").exists());
         assertTrue(new File(parent, "Alg.java").exists());
+        assertTrue(new File(parent, "IdUnionBuilder.java").exists());
+        assertFilesCount(parent, 5);
 
         // Test if sources are compilable
         testCompilation(sourcesOutputDir, compiledOutputDir);
index 01676430dd0df5759e83de06f6d903be41ea94c6..41e2eae9777c5ac3974f7533592c9841961eaddb 100644 (file)
@@ -77,7 +77,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertTrue(unionExt2.exists());
         assertTrue(unionExt3.exists());
         assertTrue(unionExt4.exists());
-        assertFilesCount(parent, 27);
+        assertFilesCount(parent, 30);
 
         // Test if sources are compilable
         testCompilation(sourcesOutputDir, compiledOutputDir);
@@ -238,13 +238,13 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertFalse(unionExt1Class.isInterface());
         assertContainsField(unionExt1Class, "_int16", Short.class);
         assertContainsField(unionExt1Class, "_int32", Integer.class);
-        assertEquals(2, unionExt1Class.getDeclaredFields().length);
+        assertEquals(3, unionExt1Class.getDeclaredFields().length);
         assertContainsMethod(unionExt1Class, Short.class, "getInt16");
         assertContainsMethod(unionExt1Class, Integer.class, "getInt32");
         assertContainsConstructor(unionExt1Class, Short.class);
         assertContainsConstructor(unionExt1Class, Integer.class);
         assertContainsConstructor(unionExt1Class, unionExt1Class);
-        assertEquals(3, unionExt1Class.getDeclaredConstructors().length);
+        assertEquals(4, unionExt1Class.getDeclaredConstructors().length);
         assertContainsDefaultMethods(unionExt1Class);
 
         // typedef union-ext2
@@ -255,20 +255,20 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertContainsConstructor(unionExt2Class, Integer.class);
         assertContainsConstructor(unionExt2Class, unionExt2Class);
         assertContainsConstructor(unionExt2Class, unionExt1Class);
-        assertEquals(4, unionExt2Class.getDeclaredConstructors().length);
+        assertEquals(5, unionExt2Class.getDeclaredConstructors().length);
 
         // typedef union-ext3
         assertFalse(unionExt3Class.isInterface());
         assertContainsField(unionExt3Class, "_string", String.class);
         assertContainsField(unionExt3Class, "_unionExt2", unionExt2Class);
         assertContainsFieldWithValue(unionExt3Class, UNITS, String.class, "object id", String.class);
-        assertEquals(3, unionExt3Class.getDeclaredFields().length);
+        assertEquals(4, unionExt3Class.getDeclaredFields().length);
         assertContainsMethod(unionExt3Class, String.class, "getString");
         assertContainsMethod(unionExt3Class, unionExt2Class, "getUnionExt2");
         assertContainsConstructor(unionExt3Class, String.class);
         assertContainsConstructor(unionExt3Class, unionExt2Class);
         assertContainsConstructor(unionExt3Class, unionExt3Class);
-        assertEquals(3, unionExt3Class.getDeclaredConstructors().length);
+        assertEquals(4, unionExt3Class.getDeclaredConstructors().length);
         assertContainsDefaultMethods(unionExt3Class);
 
         // typedef union-ext4
@@ -277,7 +277,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertContainsField(unionExt4Class, "_int32Ext2", int32Ext2Class);
         assertContainsField(unionExt4Class, "_empty", Boolean.class);
         assertContainsField(unionExt4Class, "_myDecimalType", myDecimalTypeClass);
-        assertEquals(4, unionExt4Class.getDeclaredFields().length);
+        assertEquals(5, unionExt4Class.getDeclaredFields().length);
         assertContainsMethod(unionExt4Class, unionExt3Class, "getUnionExt3");
         assertContainsMethod(unionExt4Class, int32Ext2Class, "getInt32Ext2");
         assertContainsMethod(unionExt4Class, Boolean.class, "isEmpty");
@@ -287,10 +287,10 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertContainsConstructor(unionExt4Class, Boolean.class);
         assertContainsConstructor(unionExt4Class, myDecimalTypeClass);
         assertContainsConstructor(unionExt4Class, unionExt4Class);
-        assertEquals(5, unionExt4Class.getDeclaredConstructors().length);
+        assertEquals(6, unionExt4Class.getDeclaredConstructors().length);
         assertContainsDefaultMethods(unionExt4Class);
 
-        cleanUp(sourcesOutputDir, compiledOutputDir);
+        //cleanUp(sourcesOutputDir, compiledOutputDir);
     }
 
 }
index 715251ec43f222414d939faedb4d584700e88b33..e6775e9e101b142e85aca1b4eecd6b47438034c5 100644 (file)
@@ -71,8 +71,9 @@ public interface GeneratedTransferObject extends GeneratedType {
      * @return true value if Generated Transfer Object was created from union
      *         YANG type.
      */
-    @Deprecated
     boolean isUnionType();
 
+    boolean isUnionTypeBuilder();
+
     Restrictions getRestrictions();
 }
index 3a89ccb1704aa8cfdbc509eb46afe86d3d2fba48..b80d8eb94eadcb915625ea6cc83957cf6a66f9bd 100644 (file)
@@ -84,5 +84,7 @@ public interface GeneratedTOBuilder extends GeneratedTypeBuilderBase<GeneratedTO
      */
     void setIsUnion(boolean isUnion);
 
+    void setIsUnionBuilder(boolean isUnionTypeBuilder);
+
     void setSUID(GeneratedPropertyBuilder suid);
 }
index a89eddba46425f1373997c0279d5a93733d03f41..a5c62c4bce5e1317520f1714c6be93f7b27537bd 100644 (file)
@@ -14,6 +14,7 @@ import java.util.HashMap;
 import java.util.List;\r
 import java.util.Map;\r
 \r
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;\r
 import org.opendaylight.yangtools.binding.generator.util.Types;\r
 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;\r
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions;\r
@@ -98,6 +99,8 @@ public final class BaseYangTypes {
     public static final Type UINT64_TYPE = Types.typeForClass(BigInteger.class,\r
             singleRangeRestrictions(0, new BigInteger("18446744073709551615")));\r
 \r
+    public static final Type UNION_TYPE = new UnionType();\r
+\r
     /**\r
      * <code>Type</code> representation of <code>binary</code> YANG type\r
      */\r
@@ -110,7 +113,6 @@ public final class BaseYangTypes {
      * It is undesirable to create instance of this class.\r
      */\r
     private BaseYangTypes() {\r
-\r
     }\r
 \r
     static {\r
@@ -127,6 +129,7 @@ public final class BaseYangTypes {
         typeMap.put("uint16", UINT16_TYPE);\r
         typeMap.put("uint32", UINT32_TYPE);\r
         typeMap.put("uint64", UINT64_TYPE);\r
+        typeMap.put("union", UNION_TYPE);\r
         typeMap.put("binary", BINARY_TYPE);\r
         typeMap.put("instance-identifier", INSTANCE_IDENTIFIER);\r
     }\r
@@ -193,6 +196,8 @@ public final class BaseYangTypes {
                 return Types.typeForClass(Long.class, restrictions);\r
             case "uint64":\r
                 return Types.typeForClass(BigInteger.class, restrictions);\r
+            case "union" :\r
+                return UNION_TYPE;\r
             default:\r
                 return javaTypeForSchemaDefinitionType(type, parentNode);\r
             }\r
@@ -207,6 +212,11 @@ public final class BaseYangTypes {
         public String getConstructorPropertyName(SchemaNode node) {\r
             return null;\r
         }\r
+\r
+        @Override\r
+        public String getParamNameFromType(TypeDefinition<?> type) {\r
+            return "_" + BindingGeneratorUtil.parseToValidParamName(type.getQName().getLocalName());\r
+        }\r
     };\r
 \r
     private static Restrictions singleRangeRestrictions(final Number min, final Number max) {\r
@@ -233,4 +243,19 @@ public final class BaseYangTypes {
         };\r
     }\r
 \r
+    public static final class UnionType implements Type {\r
+        @Override\r
+        public String getPackageName() {\r
+            return null;\r
+        }\r
+        @Override\r
+        public String getName() {\r
+            return "Union";\r
+        }\r
+        @Override\r
+        public String getFullyQualifiedName() {\r
+            return "Union";\r
+        }\r
+    }\r
+\r
 }\r
index 712cc1924e8277a8c094781dcaa629ac2ecb58f2..a0ff5c4867ccf502f01ebde9bd3d281caa62ac74 100644 (file)
@@ -7,83 +7,37 @@
  */
 package org.opendaylight.yangtools.sal.binding.yang.types;
 
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;
-import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToClassName;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.commons.lang3.StringEscapeUtils;
-import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
-import org.opendaylight.yangtools.binding.generator.util.TypeConstants;
-import org.opendaylight.yangtools.binding.generator.util.Types;
-import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.EnumerationBuilderImpl;
-import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
-import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
+import org.opendaylight.yangtools.binding.generator.util.*;
+import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.*;
 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
-import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType;
+import org.opendaylight.yangtools.sal.binding.model.api.*;
 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration;
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
-import org.opendaylight.yangtools.sal.binding.model.api.Restrictions;
-import org.opendaylight.yangtools.sal.binding.model.api.Type;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.*;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.YangNode;
-import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.model.api.type.*;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
-import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
-import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
-import org.opendaylight.yangtools.yang.model.util.EnumerationType;
-import org.opendaylight.yangtools.yang.model.util.ExtendedType;
-import org.opendaylight.yangtools.yang.model.util.Int16;
-import org.opendaylight.yangtools.yang.model.util.Int32;
-import org.opendaylight.yangtools.yang.model.util.Int64;
-import org.opendaylight.yangtools.yang.model.util.Int8;
-import org.opendaylight.yangtools.yang.model.util.StringType;
-import org.opendaylight.yangtools.yang.model.util.Uint16;
-import org.opendaylight.yangtools.yang.model.util.Uint32;
-import org.opendaylight.yangtools.yang.model.util.Uint64;
-import org.opendaylight.yangtools.yang.model.util.Uint8;
-import org.opendaylight.yangtools.yang.model.util.UnionType;
+import org.opendaylight.yangtools.yang.model.util.*;
 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
 import com.google.common.io.BaseEncoding;
 
 public final class TypeProviderImpl implements TypeProvider {
@@ -101,6 +55,7 @@ public final class TypeProviderImpl implements TypeProvider {
      * The map which maps schema paths to JAVA <code>Type</code>.
      */
     private final Map<SchemaPath, Type> referencedTypes;
+    private final Map<Module, Set<Type>> additionalTypes;
 
     /**
      * Creates new instance of class <code>TypeProviderImpl</code>.
@@ -116,6 +71,7 @@ public final class TypeProviderImpl implements TypeProvider {
         this.schemaContext = schemaContext;
         this.genTypeDefsContextMap = new HashMap<>();
         this.referencedTypes = new HashMap<>();
+        this.additionalTypes = new HashMap<>();
         resolveTypeDefsFromContext();
     }
 
@@ -140,6 +96,10 @@ public final class TypeProviderImpl implements TypeProvider {
         referencedTypes.put(refTypePath, refType);
     }
 
+    public Map<Module, Set<Type>> getAdditionalTypes() {
+        return additionalTypes;
+    }
+
     /**
      *
      * Converts basic YANG type <code>type</code> to JAVA <code>Type</code>.
@@ -615,7 +575,7 @@ public final class TypeProviderImpl implements TypeProvider {
 
             if ((listTypeDefinitions != null) && (basePackageName != null)) {
                 for (final TypeDefinition<?> typedef : listTypeDefinitions) {
-                    typedefToGeneratedType(basePackageName, moduleName, module.getRevision(), typedef);
+                    typedefToGeneratedType(basePackageName, module, typedef);
                 }
             }
         }
@@ -636,8 +596,10 @@ public final class TypeProviderImpl implements TypeProvider {
      *         <code>modulName</code> or <code>typedef</code> or Q name of
      *         <code>typedef</code> equals <code>null</code>
      */
-    private Type typedefToGeneratedType(final String basePackageName, final String moduleName,
-            final Date moduleRevision, final TypeDefinition<?> typedef) {
+    private Type typedefToGeneratedType(final String basePackageName, final Module module,
+            final TypeDefinition<?> typedef) {
+        final String moduleName = module.getName();
+        final Date moduleRevision = module.getRevision();
         if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
 
             final String typedefName = typedef.getQName().getLocalName();
@@ -655,6 +617,22 @@ public final class TypeProviderImpl implements TypeProvider {
                     genTOBuilder.setIsUnion(true);
                     addUnitsToGenTO(genTOBuilder, typedef.getUnits());
                     returnType = genTOBuilder.toInstance();
+                    // union builder
+                    GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(),
+                            genTOBuilder.getName() + "Builder");
+                    unionBuilder.setIsUnionBuilder(true);
+                    MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
+                    method.setReturnType(returnType);
+                    method.addParameter(Types.STRING, "defaultValue");
+                    method.setAccessModifier(AccessModifier.PUBLIC);
+                    method.setStatic(true);
+                    Set<Type> types = additionalTypes.get(module);
+                    if (types == null) {
+                        types = Sets.<Type> newHashSet(unionBuilder.toInstance());
+                        additionalTypes.put(module, types);
+                    } else {
+                        types.add(unionBuilder.toInstance());
+                    }
                 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
                     final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
                     // TODO units for typedef enum
@@ -674,7 +652,6 @@ public final class TypeProviderImpl implements TypeProvider {
                 if (returnType != null) {
                     final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(moduleName);
                     final Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
-
                     if (typeMap != null) {
                         typeMap.put(typedefName, returnType);
                     }
@@ -742,6 +719,13 @@ public final class TypeProviderImpl implements TypeProvider {
                 resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
             }
         }
+
+        final GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
+        genPropBuilder.setReturnType(Types.primitiveType("char[]", null));
+        resultTOBuilder.addEqualsIdentity(genPropBuilder);
+        resultTOBuilder.addHashIdentity(genPropBuilder);
+        resultTOBuilder.addToStringProperty(genPropBuilder);
+
         return resultTOBuilder;
     }
 
@@ -758,59 +742,57 @@ public final class TypeProviderImpl implements TypeProvider {
      * @param typeDefName
      *            string with name for generated TO
      * @return generated TO builder which represents <code>typedef</code>
-     * @throws IllegalArgumentException
+     * @throws NullPointerException
      *             <ul>
-     *             <li>if <code>basePackageName</code> equals null</li>
-     *             <li>if <code>typedef</code> equals null</li>
-     *             <li>if Q name of <code>typedef</code> equals null</li>
+     *             <li>if <code>basePackageName</code> is null</li>
+     *             <li>if <code>typedef</code> is null</li>
+     *             <li>if Qname of <code>typedef</code> is null</li>
      *             </ul>
      */
     public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
             final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) {
-        Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
-        Preconditions.checkArgument(typedef != null, "Type Definition cannot be NULL!");
-        Preconditions.checkArgument(typedef.getQName() != null,
-                "Type Definition cannot have non specified QName (QName cannot be NULL!)");
+        Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!");
+        Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!");
+        Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!");
 
         final List<GeneratedTOBuilder> generatedTOBuilders = new ArrayList<>();
+        final List<TypeDefinition<?>> unionTypes = typedef.getTypes();
 
-        if (typedef != null) {
-            final List<TypeDefinition<?>> unionTypes = typedef.getTypes();
+        final GeneratedTOBuilder unionGenTOBuilder;
+        if (typeDefName != null && !typeDefName.isEmpty()) {
+            final String typeName = parseToClassName(typeDefName);
+            unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
+        } else {
+            unionGenTOBuilder = typedefToTransferObject(basePackageName, typedef);
+        }
 
-            final GeneratedTOBuilder unionGenTOBuilder;
-            if (typeDefName != null && !typeDefName.isEmpty()) {
-                final String typeName = parseToClassName(typeDefName);
-                unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
+        generatedTOBuilders.add(unionGenTOBuilder);
+        unionGenTOBuilder.setIsUnion(true);
+        final List<String> regularExpressions = new ArrayList<String>();
+        for (final TypeDefinition<?> unionType : unionTypes) {
+            final String unionTypeName = unionType.getQName().getLocalName();
+            if (unionType instanceof UnionType) {
+                generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionType) unionType,
+                        basePackageName, parentNode));
+            } else if (unionType instanceof ExtendedType) {
+                resolveExtendedSubtypeAsUnion(unionGenTOBuilder, (ExtendedType) unionType, regularExpressions,
+                        parentNode);
+            } else if (unionType instanceof EnumTypeDefinition) {
+                final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
+                        unionTypeName, unionGenTOBuilder);
+                updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
             } else {
-                unionGenTOBuilder = typedefToTransferObject(basePackageName, typedef);
-            }
-            generatedTOBuilders.add(unionGenTOBuilder);
-            unionGenTOBuilder.setIsUnion(true);
-            final List<String> regularExpressions = new ArrayList<String>();
-            for (final TypeDefinition<?> unionType : unionTypes) {
-                final String unionTypeName = unionType.getQName().getLocalName();
-                if (unionType instanceof UnionType) {
-                    generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionType) unionType,
-                            basePackageName, parentNode));
-                } else if (unionType instanceof ExtendedType) {
-                    resolveExtendedSubtypeAsUnion(unionGenTOBuilder, (ExtendedType) unionType, unionTypeName,
-                            regularExpressions, parentNode);
-                } else if (unionType instanceof EnumTypeDefinition) {
-                    final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
-                            unionTypeName, unionGenTOBuilder);
-                    updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
-                } else {
-                    final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
-                            unionType, parentNode);
-                    updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
-                }
-            }
-            if (!regularExpressions.isEmpty()) {
-                addStringRegExAsConstant(unionGenTOBuilder, regularExpressions);
+                final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(unionType,
+                        parentNode);
+                updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
             }
-
-            storeGenTO(typedef, unionGenTOBuilder, parentNode);
         }
+        if (!regularExpressions.isEmpty()) {
+            addStringRegExAsConstant(unionGenTOBuilder, regularExpressions);
+        }
+
+        storeGenTO(typedef, unionGenTOBuilder, parentNode);
+
         return generatedTOBuilders;
     }
 
@@ -871,9 +853,10 @@ public final class TypeProviderImpl implements TypeProvider {
      *            list of strings with the regular expressions
      */
     private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
-            final ExtendedType unionSubtype, final String unionTypeName, final List<String> regularExpressions,
+            final ExtendedType unionSubtype, final List<String> regularExpressions,
             final SchemaNode parentNode) {
-        final Type genTO = findGenTO(unionTypeName, parentNode);
+        final String unionTypeName = unionSubtype.getQName().getLocalName();
+        final Type genTO = findGenTO(unionTypeName, unionSubtype);
         if (genTO != null) {
             updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, genTO.getName());
         } else {
@@ -1245,7 +1228,7 @@ public final class TypeProviderImpl implements TypeProvider {
         }
     }
 
-    private void addUnitsToGenTO(GeneratedTOBuilder to, String units) {
+    public void addUnitsToGenTO(GeneratedTOBuilder to, String units) {
         if (units != null && !units.isEmpty()) {
             to.addConstant(Types.STRING, "_UNITS", "\"" + units + "\"");
             GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS");
@@ -1337,18 +1320,19 @@ public final class TypeProviderImpl implements TypeProvider {
         } else if (base instanceof Uint64) {
             result = typeToDef(BigInteger.class, defaultValue);
         } else if (base instanceof UnionTypeDefinition) {
-            throw new UnsupportedOperationException("Cannot get default construction for union type");
+            result = unionToDef(node);
         } else {
             result = "";
         }
         sb.append(result);
 
-        if (type instanceof ExtendedType && !(base instanceof LeafrefTypeDefinition) && !(base instanceof EnumerationType)) {
+        if (type instanceof ExtendedType && !(base instanceof LeafrefTypeDefinition)
+                && !(base instanceof EnumerationType) && !(base instanceof UnionTypeDefinition)) {
             QName qname = type.getPath().getPath().get(0);
             Module m = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), qname.getRevision());
             String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(m);
             String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
-            String className = packageName + "." + parseToClassName(typeQName.getLocalName());
+            String className = packageName + "." + BindingMapping.getClassName(typeQName);
             sb.insert(0, "new " + className + "(");
             sb.insert(sb.length(), ")");
         }
@@ -1454,6 +1438,65 @@ public final class TypeProviderImpl implements TypeProvider {
         return null;
     }
 
+    private String unionToDef(LeafSchemaNode node) {
+        String parentName;
+        String className;
+
+        if (node.getType() instanceof ExtendedType) {
+            ExtendedType type = (ExtendedType) node.getType();
+            QName typeQName = type.getQName();
+            Module module = null;
+            Set<Module> modules = schemaContext.findModuleByNamespace(typeQName.getNamespace());
+            if (modules.size() > 1) {
+                for (Module m : modules) {
+                    if (m.getRevision().equals(typeQName.getRevision())) {
+                        module = m;
+                        break;
+                    }
+                }
+                if (module == null) {
+                    List<Module> modulesList = new ArrayList<>(modules);
+                    Collections.sort(modulesList, new Comparator<Module>() {
+                        @Override
+                        public int compare(Module o1, Module o2) {
+                            return o1.getRevision().compareTo(o2.getRevision());
+                        }
+                    });
+                    module = modulesList.get(0);
+                }
+            } else {
+                module = modules.iterator().next();
+            }
+
+            String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
+            className = basePackageName + "." + BindingMapping.getClassName(typeQName);
+        } else {
+            YangNode parent = node.getParent();
+            if (parent instanceof Module) {
+                parentName = parseToClassName(((Module) parent).getName()) + "Data";
+                String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName((Module) parent);
+                className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
+            } else {
+                Module parentModule = getParentModule(node);
+                String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parentModule);
+                String packageName = packageNameForGeneratedType(basePackageName, node.getType().getPath());
+                className = packageName + "." + BindingMapping.getClassName(node.getQName());
+            }
+        }
+        return union(className, node.getDefault(), node);
+    }
+
+    private String union(String className, String defaultValue, LeafSchemaNode node) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("new " + className + "(");
+        sb.append("\"");
+        sb.append(defaultValue);
+        sb.append("\"");
+        sb.append(".toCharArray()");
+        sb.append(")");
+        return sb.toString();
+    }
+
     @Override
     public String getConstructorPropertyName(SchemaNode node) {
         if (node instanceof TypeDefinition<?>) {
@@ -1463,4 +1506,9 @@ public final class TypeProviderImpl implements TypeProvider {
         }
     }
 
+    @Override
+    public String getParamNameFromType(TypeDefinition<?> type) {
+        return BindingGeneratorUtil.parseToValidParamName(type.getQName().getLocalName());
+    }
+
 }
index 8fde4501486af236b764b5ae4f77e958cfc917f5..a273c6b8b729c66d048f795c8304d77dcd90b816 100644 (file)
@@ -30,7 +30,10 @@ import org.sonatype.plexus.build.incremental.BuildContext;
 import com.google.common.base.Preconditions;
 
 public final class CodeGeneratorImpl implements CodeGenerator, BuildContextAware {
+    private static final String FS = File.separator;
     private BuildContext buildContext;
+    private File projectBaseDir;
+    private Map<String, String> additionalConfig;
 
     @Override
     public Collection<File> generateSources(final SchemaContext context, final File outputDir,
@@ -47,7 +50,17 @@ public final class CodeGeneratorImpl implements CodeGenerator, BuildContextAware
         final List<Type> types = bindingGenerator.generateTypes(context, yangModules);
         final GeneratorJavaFile generator = new GeneratorJavaFile(buildContext, new HashSet<>(types));
 
-        return generator.generateToFile(outputBaseDir);
+        File persistentSourcesDir = null;
+        if (additionalConfig != null) {
+            String persistenSourcesPath = additionalConfig.get("persistentSourcesDir");
+            if (persistenSourcesPath != null) {
+                persistentSourcesDir = new File(persistenSourcesPath);
+            }
+        }
+        if (persistentSourcesDir == null) {
+            persistentSourcesDir = new File(projectBaseDir, "src" + FS + "main" + FS + "java");
+        }
+        return generator.generateToFile(outputBaseDir, persistentSourcesDir);
     }
 
     @Override
@@ -58,7 +71,7 @@ public final class CodeGeneratorImpl implements CodeGenerator, BuildContextAware
 
     @Override
     public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
-        // no additional config utilized
+        this.additionalConfig = additionalConfiguration;
     }
 
     @Override
@@ -68,7 +81,7 @@ public final class CodeGeneratorImpl implements CodeGenerator, BuildContextAware
 
     @Override
     public void setMavenProject(MavenProject project) {
-        // no additional information needed
+        this.projectBaseDir = project.getBasedir();
     }
 
     @Override
diff --git a/model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/HostBuilder.java b/model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/HostBuilder.java
new file mode 100644 (file)
index 0000000..eddb222
--- /dev/null
@@ -0,0 +1,48 @@
+package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+**/
+public class HostBuilder {
+
+    public static Host getDefaultInstance(String defaultValue) {
+        String ipv4Pattern = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\\p{N}\\p{L}]+)?";
+        String ipv6Pattern1 = "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\\p{N}\\p{L}]+)?";
+        String ipv6Pattern2 = "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?";
+        String domainPattern = "((([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.)*([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)|\\.";
+
+        List<String> matchers = new ArrayList<>();
+        if (defaultValue.matches(ipv4Pattern)) {
+            matchers.add(Ipv4Address.class.getSimpleName());
+        }
+        if (defaultValue.matches(ipv6Pattern1) && defaultValue.matches(ipv6Pattern2)) {
+            matchers.add(Ipv6Address.class.getSimpleName());
+        }
+        if (defaultValue.matches(domainPattern)) {
+            matchers.add(DomainName.class.getSimpleName());
+        }
+        if (matchers.size() > 1) {
+            throw new IllegalArgumentException("Cannot create Host from " + defaultValue + ". Value is ambigious for "
+                    + matchers);
+        }
+
+        if (defaultValue.matches(ipv4Pattern)) {
+            Ipv4Address ipv4 = new Ipv4Address(defaultValue);
+            IpAddress ipAddress = new IpAddress(ipv4);
+            return new Host(ipAddress);
+        }
+        if (defaultValue.matches(ipv6Pattern1) && defaultValue.matches(ipv6Pattern2)) {
+            Ipv6Address ipv6 = new Ipv6Address(defaultValue);
+            IpAddress ipAddress = new IpAddress(ipv6);
+            return new Host(ipAddress);
+        }
+        if (defaultValue.matches(domainPattern)) {
+            DomainName domainName = new DomainName(defaultValue);
+            return new Host(domainName);
+        }
+        throw new IllegalArgumentException("Cannot create Host from " + defaultValue);
+    }
+
+}
diff --git a/model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/IpAddressBuilder.java b/model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/IpAddressBuilder.java
new file mode 100644 (file)
index 0000000..16705a0
--- /dev/null
@@ -0,0 +1,38 @@
+package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+**/
+public class IpAddressBuilder {
+
+    public static IpAddress getDefaultInstance(String defaultValue) {
+        String ipv4Pattern = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\\p{N}\\p{L}]+)?";
+        String ipv6Pattern1 = "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\\p{N}\\p{L}]+)?";
+        String ipv6Pattern2 = "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?";
+
+        List<String> matchers = new ArrayList<>();
+        if (defaultValue.matches(ipv4Pattern)) {
+            matchers.add(Ipv4Address.class.getSimpleName());
+        }
+        if (defaultValue.matches(ipv6Pattern1) && defaultValue.matches(ipv6Pattern2)) {
+            matchers.add(Ipv6Address.class.getSimpleName());
+        }
+        if (matchers.size() > 1) {
+            throw new IllegalArgumentException("Cannot create IpAddress from " + defaultValue
+                    + ". Value is ambigious for " + matchers);
+        }
+
+        if (defaultValue.matches(ipv4Pattern)) {
+            Ipv4Address ipv4 = new Ipv4Address(defaultValue);
+            return new IpAddress(ipv4);
+        }
+        if (defaultValue.matches(ipv6Pattern1) && defaultValue.matches(ipv6Pattern2)) {
+            Ipv6Address ipv6 = new Ipv6Address(defaultValue);
+            return new IpAddress(ipv6);
+        }
+        throw new IllegalArgumentException("Cannot create IpAddress from " + defaultValue);
+    }
+
+}
diff --git a/model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/IpPrefixBuilder.java b/model/ietf/ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev100924/IpPrefixBuilder.java
new file mode 100644 (file)
index 0000000..0e9d4c7
--- /dev/null
@@ -0,0 +1,38 @@
+package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+**/
+public class IpPrefixBuilder {
+
+    public static IpPrefix getDefaultInstance(String defaultValue) {
+        String ipv4Pattern = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))";
+        String ipv6Pattern1 = "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))";
+        String ipv6Pattern2 = "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(/.+)";
+
+        List<String> matchers = new ArrayList<>();
+        if (defaultValue.matches(ipv4Pattern)) {
+            matchers.add(Ipv4Address.class.getSimpleName());
+        }
+        if (defaultValue.matches(ipv6Pattern1) && defaultValue.matches(ipv6Pattern2)) {
+            matchers.add(Ipv6Address.class.getSimpleName());
+        }
+        if (matchers.size() > 1) {
+            throw new IllegalArgumentException("Cannot create IpPrefix from " + defaultValue
+                    + ". Value is ambigious for " + matchers);
+        }
+
+        if (defaultValue.matches(ipv4Pattern)) {
+            Ipv4Prefix ipv4 = new Ipv4Prefix(defaultValue);
+            return new IpPrefix(ipv4);
+        }
+        if (defaultValue.matches(ipv6Pattern1) && defaultValue.matches(ipv6Pattern2)) {
+            Ipv6Prefix ipv6 = new Ipv6Prefix(defaultValue);
+            return new IpPrefix(ipv6);
+        }
+        throw new IllegalArgumentException("Cannot create IpPrefix from " + defaultValue);
+    }
+
+}