*/
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.net.URI;
+import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.sal.binding.generator.spi.TypeProvider;
+import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier;
import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType;
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.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.MethodSignatureBuilder;
+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.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.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.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>.
* @throws IllegalArgumentException
* <ul>
* <li>if <code>typeDefinition</code> equal null</li>
- * <li>if Q name of <code>typeDefinition</code> equal null</li>
+ * <li>if Qname of <code>typeDefinition</code> equal null</li>
* <li>if name of <code>typeDefinition</code> equal null</li>
* </ul>
*/
} else {
returnType = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode);
if (returnType == null) {
- returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition,
- parentNode, r);
+ returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(typeDefinition.getQName()
+ .getLocalName());
}
}
// TODO: add throw exception when we will be able to resolve ALL yang
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 BitsTypeDefinition) {
String parentName;
String className;
- YangNode parent = node.getParent();
- if (parent instanceof Module) {
- parentName = parseToClassName(((Module) parent).getName()) + "Data";
- String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName((Module) parent);
- className = basePackageName + "." + parentName + "." + parseToClassName(node.getQName().getLocalName());
+ SchemaPath nodePath = node.getPath();
+ Module parent = getParentModule(node);
+ if (nodePath.getPath().size() == 1) {
+ parentName = BindingMapping.getClassName((parent).getName()) + "Data";
+ String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parent);
+ className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
} else {
- Module parentModule = getParentModule(node);
- String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parentModule);
+ String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parent);
String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
- parentName = parseToClassName(((SchemaNode) parent).getQName().getLocalName());
- className = packageName + "." + parentName + "." + parseToClassName(node.getQName().getLocalName());
+ parentName = BindingMapping.getClassName(((SchemaNode) parent).getQName());
+ className = packageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
}
result = bitsToDef((BitsTypeDefinition) base, className, defaultValue, type instanceof ExtendedType);
} else if (base instanceof BooleanTypeDefinition) {
String newDefVal = new String(defValArray);
String className;
if (type instanceof ExtendedType) {
- QName qname = type.getPath().getPath().get(0);
- Module m = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), qname.getRevision());
+ Module m = getParentModule(type);
String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(m);
String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
- className = packageName + "." + parseToClassName(typeQName.getLocalName());
+ className = packageName + "." + BindingMapping.getClassName(typeQName);
} else {
Module parentModule = getParentModule(node);
String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parentModule);
String packageName = packageNameForGeneratedType(basePackageName, node.getPath());
- className = packageName + "." + parseToClassName(node.getQName().getLocalName());
+ className = packageName + "." + BindingMapping.getClassName(node.getQName());
}
result = className + "." + newDefVal;
} else if (base instanceof IdentityrefTypeDefinition) {
} 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)) {
- QName qname = type.getPath().getPath().get(0);
- Module m = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), qname.getRevision());
+ if (type instanceof ExtendedType && !(base instanceof LeafrefTypeDefinition)
+ && !(base instanceof EnumerationType) && !(base instanceof UnionTypeDefinition)) {
+ Module m = getParentModule(type);
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 sb.toString();
}
- private Module getParentModule(YangNode node) {
- if (node instanceof Module) {
- return (Module) node;
- }
-
- YangNode parent = null;
- if (node instanceof DataSchemaNode) {
- parent = ((DataSchemaNode) node).getParent();
- } else if (node instanceof DataNodeContainer) {
- parent = ((DataNodeContainer) node).getParent();
- } else {
- parent = null;
- }
-
- while (parent != null && !(parent instanceof Module)) {
- if (parent instanceof DataSchemaNode) {
- parent = ((DataSchemaNode) parent).getParent();
- } else if (parent instanceof DataNodeContainer) {
- parent = ((DataNodeContainer) parent).getParent();
- } else {
- parent = null;
- }
- }
- return (Module) parent;
+ private Module getParentModule(SchemaNode node) {
+ QName qname = node.getPath().getPath().get(0);
+ URI namespace = qname.getNamespace();
+ Date revision = qname.getRevision();
+ return schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
}
private String leafrefToDef(LeafSchemaNode parentNode, LeafrefTypeDefinition leafrefType) {
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 {
+ SchemaPath nodePath = node.getPath();
+ if (nodePath.getPath().size() == 1) {
+ QName first = nodePath.getPath().get(0);
+ URI namespace = first.getNamespace();
+ Date revision = first.getRevision();
+ Module parent = schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
+ parentName = BindingMapping.getClassName((parent).getName()) + "Data";
+ String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parent);
+ className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
+ } else {
+ QName first = node.getPath().getPath().get(0);
+ URI namespace = first.getNamespace();
+ Date revision = first.getRevision();
+ Module parentModule = schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
+ 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());
+ }
+
}