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>
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()
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;
}
}
}
}
- }
+ }\r
\r
private def GeneratedTypeBuilder processDataSchemaNode(Module module, String basePackageName,
GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, DataSchemaNode node) {
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;
}
(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) {
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
}
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);
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) ).
*/
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;
"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"));
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"));
"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"));
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
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
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
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;
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();
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 {
String getTypeDefaultConstruction(LeafSchemaNode node);\r
\r
String getConstructorPropertyName(SchemaNode node);\r
+\r
+ String getParamNameFromType(TypeDefinition<?> type);\r
+\r
}\r
\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
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
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
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
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
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
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
\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
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
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
+ »'''
+
}
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;
* 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);
}
«ENDFOR»\r
« ENDIF»\r
'''\r
+\r
/**\r
* Template method which generates inner classes inside this interface.\r
* \r
«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
«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
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
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
--- /dev/null
+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 ""
+ }
+ }
+
+}
-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»
+ }
+ '''
+
+}
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);
assertTrue(unionExt2.exists());
assertTrue(unionExt3.exists());
assertTrue(unionExt4.exists());
- assertFilesCount(parent, 27);
+ assertFilesCount(parent, 30);
// Test if sources are compilable
testCompilation(sourcesOutputDir, compiledOutputDir);
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
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
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");
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);
}
}
* @return true value if Generated Transfer Object was created from union
* YANG type.
*/
- @Deprecated
boolean isUnionType();
+ boolean isUnionTypeBuilder();
+
Restrictions getRestrictions();
}
*/
void setIsUnion(boolean isUnion);
+ void setIsUnionBuilder(boolean isUnionTypeBuilder);
+
void setSUID(GeneratedPropertyBuilder suid);
}
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
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
* It is undesirable to create instance of this class.\r
*/\r
private BaseYangTypes() {\r
-\r
}\r
\r
static {\r
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
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
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
};\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
*/
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 {
* 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>.
this.schemaContext = schemaContext;
this.genTypeDefsContextMap = new HashMap<>();
this.referencedTypes = new HashMap<>();
+ this.additionalTypes = new HashMap<>();
resolveTypeDefsFromContext();
}
referencedTypes.put(refTypePath, refType);
}
+ public Map<Module, Set<Type>> getAdditionalTypes() {
+ return additionalTypes;
+ }
+
/**
*
* Converts basic YANG type <code>type</code> to JAVA <code>Type</code>.
if ((listTypeDefinitions != null) && (basePackageName != null)) {
for (final TypeDefinition<?> typedef : listTypeDefinitions) {
- typedefToGeneratedType(basePackageName, moduleName, module.getRevision(), typedef);
+ typedefToGeneratedType(basePackageName, module, typedef);
}
}
}
* <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();
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
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);
}
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;
}
* @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;
}
* 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 {
}
}
- 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");
} 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(), ")");
}
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<?>) {
}
}
+ @Override
+ public String getParamNameFromType(TypeDefinition<?> type) {
+ return BindingGeneratorUtil.parseToValidParamName(type.getQName().getLocalName());
+ }
+
}
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,
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
@Override
public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
- // no additional config utilized
+ this.additionalConfig = additionalConfiguration;
}
@Override
@Override
public void setMavenProject(MavenProject project) {
- // no additional information needed
+ this.projectBaseDir = project.getBasedir();
}
@Override
--- /dev/null
+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);
+ }
+
+}
--- /dev/null
+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);
+ }
+
+}
--- /dev/null
+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);
+ }
+
+}