import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
+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 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.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.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.parser.util.ModuleDependencySort;
import com.google.common.base.Preconditions;
+import com.google.common.io.BaseEncoding;
public final class TypeProviderImpl implements TypeProvider {
/**
private final SchemaContext schemaContext;
/**
- * The outter map maps module names to the map of the types for the module.
- * The inner map maps the name of the concrete type to the JAVA
- * <code>Type</code> (usually it is generated TO).
+ * Map<moduleName, Map<moduleDate, Map<typeName, type>>>
*/
- private Map<String, Map<String, Type>> genTypeDefsContextMap;
+ private Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap;
/**
* The map which maps schema paths to JAVA <code>Type</code>.
* </ul>
*/
@Override
- public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode, Restrictions r) {
+ public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
+ Restrictions r) {
Type returnType = null;
Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
if (typeDefinition.getQName() == null) {
final Module module = findParentModule(schemaContext, typeDefinition);
Restrictions r = BindingGeneratorUtil.getRestrictions(typeDefinition);
if (module != null) {
- final Map<String, Type> genTOs = genTypeDefsContextMap.get(module.getName());
+ final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(module.getName());
+ final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
if (genTOs != null) {
returnType = genTOs.get(typedefName);
}
final Module module = findParentModule(schemaContext, parentNode);
if (module != null) {
- final Map<String, Type> genTOs = genTypeDefsContextMap.get(module.getName());
+ final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(module.getName());
+ final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
if (genTOs != null) {
returnType = genTOs.get(typedefName);
}
private TypeDefinition<?> baseTypeDefForExtendedType(final TypeDefinition<?> extendTypeDef) {
Preconditions.checkArgument(extendTypeDef != null, "Type Definiition reference cannot be NULL!");
final TypeDefinition<?> baseTypeDef = extendTypeDef.getBaseType();
- if (baseTypeDef instanceof ExtendedType) {
+ if (baseTypeDef == null) {
+ return extendTypeDef;
+ } else if (baseTypeDef instanceof ExtendedType) {
return baseTypeDefForExtendedType(baseTypeDef);
} else {
return baseTypeDef;
}
final List<Module> modulesSortedByDependency = ModuleDependencySort.sort(modulesArray);
+ for (final Module module : modulesSortedByDependency) {
+ Map<Date, Map<String, Type>> dateTypeMap = genTypeDefsContextMap.get(module.getName());
+ if (dateTypeMap == null) {
+ dateTypeMap = new HashMap<>();
+ }
+ final Map<String, Type> typeMap = new HashMap<>();
+ dateTypeMap.put(module.getRevision(), typeMap);
+ genTypeDefsContextMap.put(module.getName(), dateTypeMap);
+ }
+
for (final Module module : modulesSortedByDependency) {
if (module == null) {
continue;
final List<TypeDefinition<?>> typeDefinitions = it.allTypedefs();
final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
- final Map<String, Type> typeMap = new HashMap<>();
- genTypeDefsContextMap.put(moduleName, typeMap);
-
if ((listTypeDefinitions != null) && (basePackageName != null)) {
for (final TypeDefinition<?> typedef : listTypeDefinitions) {
- typedefToGeneratedType(basePackageName, moduleName, typedef);
+ typedefToGeneratedType(basePackageName, moduleName, module.getRevision(), typedef);
}
}
}
* <code>typedef</code> equals <code>null</code>
*/
private Type typedefToGeneratedType(final String basePackageName, final String moduleName,
- final TypeDefinition<?> typedef) {
+ final Date moduleRevision, final TypeDefinition<?> typedef) {
if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
final String typedefName = typedef.getQName().getLocalName();
} else if (innerTypeDefinition instanceof UnionTypeDefinition) {
final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
(UnionTypeDefinition) innerTypeDefinition, typedefName, typedef);
+ genTOBuilder.setTypedef(true);
genTOBuilder.setIsUnion(true);
addUnitsToGenTO(genTOBuilder, typedef.getUnits());
returnType = genTOBuilder.toInstance();
final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForBitsTypeDefinition(
basePackageName, bitsTypeDefinition, typedefName);
+ genTOBuilder.setTypedef(true);
addUnitsToGenTO(genTOBuilder, typedef.getUnits());
returnType = genTOBuilder.toInstance();
} else {
returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType);
}
if (returnType != null) {
- final Map<String, Type> typeMap = genTypeDefsContextMap.get(moduleName);
+ 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);
}
*/
private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition<?> typedef,
final Type javaType) {
- if (javaType != null) {
- final String propertyName = "value";
-
- final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef);
- genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef));
- final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
- genPropBuilder.setReturnType(javaType);
- genTOBuilder.addEqualsIdentity(genPropBuilder);
- genTOBuilder.addHashIdentity(genPropBuilder);
- genTOBuilder.addToStringProperty(genPropBuilder);
- if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef instanceof ExtendedType) {
- final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
- addStringRegExAsConstant(genTOBuilder, regExps);
- }
- addUnitsToGenTO(genTOBuilder, typedef.getUnits());
- return genTOBuilder.toInstance();
+ Preconditions.checkNotNull(javaType, "javaType cannot be null");
+ final String propertyName = "value";
+
+ final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef);
+ genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef));
+ final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
+ genPropBuilder.setReturnType(javaType);
+ genTOBuilder.addEqualsIdentity(genPropBuilder);
+ genTOBuilder.addHashIdentity(genPropBuilder);
+ genTOBuilder.addToStringProperty(genPropBuilder);
+ if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef instanceof ExtendedType) {
+ final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
+ addStringRegExAsConstant(genTOBuilder, regExps);
}
- return null;
+ addUnitsToGenTO(genTOBuilder, typedef.getUnits());
+ genTOBuilder.setTypedef(true);
+ return genTOBuilder.toInstance();
}
/**
typedef, typeDefName, parentNode);
GeneratedTOBuilder resultTOBuilder = null;
if (!genTOBuilders.isEmpty()) {
- resultTOBuilder = genTOBuilders.get(0);
- genTOBuilders.remove(0);
+ resultTOBuilder = genTOBuilders.remove(0);
for (GeneratedTOBuilder genTOBuilder : genTOBuilders) {
resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
}
private Type findGenTO(final String searchedTypeName, final SchemaNode parentNode) {
final Module typeModule = findParentModule(schemaContext, parentNode);
if (typeModule != null && typeModule.getName() != null) {
- final Map<String, Type> genTOs = genTypeDefsContextMap.get(typeModule.getName());
+ final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(typeModule.getName());
+ final Map<String, Type> genTOs = modulesByDate.get(typeModule.getRevision());
if (genTOs != null) {
return genTOs.get(searchedTypeName);
}
*/
private void storeGenTO(TypeDefinition<?> newTypeDef, GeneratedTOBuilder genTOBuilder, SchemaNode parentNode) {
if (!(newTypeDef instanceof UnionType)) {
- Map<String, Type> genTOsMap = null;
+
final Module parentModule = findParentModule(schemaContext, parentNode);
if (parentModule != null && parentModule.getName() != null) {
- genTOsMap = genTypeDefsContextMap.get(parentModule.getName());
+ Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(parentModule.getName());
+ Map<String, Type> genTOsMap = modulesByDate.get(parentModule.getRevision());
genTOsMap.put(newTypeDef.getQName().getLocalName(), genTOBuilder.toInstance());
}
}
* <li>if <code>typedefName</code> equals null</li>
* </ul>
*/
- private GeneratedTransferObject provideGeneratedTOFromExtendedType(final TypeDefinition<?> typedef, final ExtendedType innerExtendedType,
- final String basePackageName) {
+ private GeneratedTransferObject provideGeneratedTOFromExtendedType(final TypeDefinition<?> typedef,
+ final ExtendedType innerExtendedType, final String basePackageName) {
Preconditions.checkArgument(innerExtendedType != null, "Extended type cannot be NULL!");
Preconditions.checkArgument(basePackageName != null, "String with base package name cannot be NULL!");
final String classTypedefName = parseToClassName(typedefName);
final String innerTypeDef = innerExtendedType.getQName().getLocalName();
final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, classTypedefName);
+ genTOBuilder.setTypedef(true);
Restrictions r = BindingGeneratorUtil.getRestrictions(typedef);
genTOBuilder.setRestrictions(r);
genTOBuilder.setIsUnion(true);
}
+ Map<Date, Map<String, Type>> modulesByDate = null;
Map<String, Type> typeMap = null;
final Module parentModule = findParentModule(schemaContext, innerExtendedType);
if (parentModule != null) {
- typeMap = genTypeDefsContextMap.get(parentModule.getName());
+ modulesByDate = genTypeDefsContextMap.get(parentModule.getName());
+ typeMap = modulesByDate.get(parentModule.getRevision());
}
if (typeMap != null) {
}
}
+ @Override
+ public String getTypeDefaultConstruction(LeafSchemaNode node) {
+ return getTypeDefaultConstruction(node, node.getDefault());
+ }
+
+ public String getTypeDefaultConstruction(LeafSchemaNode node, String defaultValue) {
+ TypeDefinition<?> type = node.getType();
+ QName typeQName = type.getQName();
+ TypeDefinition<?> base = baseTypeDefForExtendedType(type);
+ Preconditions.checkNotNull(type, "Cannot provide default construction for null type of " + node);
+ Preconditions.checkNotNull(defaultValue, "Cannot provide default construction for null default statement of "
+ + node);
+
+ StringBuilder sb = new StringBuilder();
+ String result = null;
+ if (base instanceof BinaryTypeDefinition) {
+ result = binaryToDef(defaultValue);
+ } 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());
+ } else {
+ Module parentModule = getParentModule(node);
+ String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parentModule);
+ String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
+ parentName = parseToClassName(((SchemaNode) parent).getQName().getLocalName());
+ className = packageName + "." + parentName + "." + parseToClassName(node.getQName().getLocalName());
+ }
+ result = bitsToDef((BitsTypeDefinition) base, className, defaultValue, type instanceof ExtendedType);
+ } else if (base instanceof BooleanTypeDefinition) {
+ result = typeToDef(Boolean.class, defaultValue);
+ } else if (base instanceof DecimalTypeDefinition) {
+ result = typeToDef(BigDecimal.class, defaultValue);
+ } else if (base instanceof EmptyTypeDefinition) {
+ result = typeToDef(Boolean.class, defaultValue);
+ } else if (base instanceof EnumTypeDefinition) {
+ char[] defValArray = defaultValue.toCharArray();
+ char first = Character.toUpperCase(defaultValue.charAt(0));
+ defValArray[0] = first;
+ 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());
+ String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(m);
+ String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
+ className = packageName + "." + parseToClassName(typeQName.getLocalName());
+ } else {
+ Module parentModule = getParentModule(node);
+ String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parentModule);
+ String packageName = packageNameForGeneratedType(basePackageName, node.getPath());
+ className = packageName + "." + parseToClassName(node.getQName().getLocalName());
+ }
+ result = className + "." + newDefVal;
+ } else if (base instanceof IdentityrefTypeDefinition) {
+ throw new UnsupportedOperationException("Cannot get default construction for identityref type");
+ } else if (base instanceof InstanceIdentifierTypeDefinition) {
+ throw new UnsupportedOperationException("Cannot get default construction for instance-identifier type");
+ } else if (base instanceof Int8) {
+ result = typeToDef(Byte.class, defaultValue);
+ } else if (base instanceof Int16) {
+ result = typeToDef(Short.class, defaultValue);
+ } else if (base instanceof Int32) {
+ result = typeToDef(Integer.class, defaultValue);
+ } else if (base instanceof Int64) {
+ result = typeToDef(Long.class, defaultValue);
+ } else if (base instanceof LeafrefTypeDefinition) {
+ result = leafrefToDef(node, (LeafrefTypeDefinition) base);
+ } else if (base instanceof StringTypeDefinition) {
+ result = "\"" + defaultValue + "\"";
+ } else if (base instanceof Uint8) {
+ result = typeToDef(Short.class, defaultValue);
+ } else if (base instanceof Uint16) {
+ result = typeToDef(Integer.class, defaultValue);
+ } else if (base instanceof Uint32) {
+ result = typeToDef(Long.class, defaultValue);
+ } 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");
+ } 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());
+ String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(m);
+ String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
+ String className = packageName + "." + parseToClassName(typeQName.getLocalName());
+ sb.insert(0, "new " + className + "(");
+ sb.insert(sb.length(), ")");
+ }
+
+ return sb.toString();
+ }
+
+ private String typeToDef(Class<?> clazz, String defaultValue) {
+ return "new " + clazz.getName() + "(\"" + defaultValue + "\")";
+ }
+
+ private String binaryToDef(String defaultValue) {
+ StringBuilder sb = new StringBuilder();
+ BaseEncoding en = BaseEncoding.base64();
+ byte[] encoded = en.decode(defaultValue);
+ sb.append("new byte[] {");
+ for (int i = 0; i < encoded.length; i++) {
+ sb.append(encoded[i]);
+ if (i != encoded.length - 1) {
+ sb.append(", ");
+ }
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ private String bitsToDef(BitsTypeDefinition type, String className, String defaultValue, boolean isExt) {
+ List<Bit> bits = new ArrayList<>(type.getBits());
+ Collections.sort(bits, new Comparator<Bit>() {
+ @Override
+ public int compare(Bit o1, Bit o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ StringBuilder sb = new StringBuilder();
+ sb.append(isExt ? "" : "new " + className + "(");
+ for (int i = 0; i < bits.size(); i++) {
+ if (bits.get(i).getName().equals(defaultValue)) {
+ sb.append(true);
+ } else {
+ sb.append(false);
+ }
+ if (i != bits.size() - 1) {
+ sb.append(", ");
+ }
+ }
+ sb.append(isExt ? "" : ")");
+ 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 String leafrefToDef(LeafSchemaNode parentNode, LeafrefTypeDefinition leafrefType) {
+ Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
+ Preconditions.checkArgument(leafrefType.getPathStatement() != null,
+ "The Path Statement for Leafref Type Definition cannot be NULL!");
+
+ final RevisionAwareXPath xpath = leafrefType.getPathStatement();
+ final String strXPath = xpath.toString();
+
+ if (strXPath != null) {
+ if (strXPath.contains("[")) {
+ return "new java.lang.Object()";
+ } else {
+ final Module module = findParentModule(schemaContext, parentNode);
+ if (module != null) {
+ final SchemaNode dataNode;
+ if (xpath.isAbsolute()) {
+ dataNode = findDataSchemaNode(schemaContext, module, xpath);
+ } else {
+ dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
+ }
+ String result = getTypeDefaultConstruction((LeafSchemaNode) dataNode, parentNode.getDefault());
+ return result;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getConstructorPropertyName(SchemaNode node) {
+ if (node instanceof TypeDefinition<?>) {
+ return "value";
+ } else {
+ return "";
+ }
+ }
+
}