/*
* Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.mdsal.binding.javav2.generator.yang.types;
import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl.addUnitsToGenTO;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang3.StringEscapeUtils;
import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
import org.opendaylight.mdsal.binding.javav2.generator.util.TypeConstants;
import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.EnumerationBuilderImpl;
import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
import org.opendaylight.mdsal.binding.javav2.model.api.ConcreteType;
import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration;
import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
import org.opendaylight.mdsal.binding.javav2.model.api.Type;
import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.Status;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
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;
/**
* Auxiliary util class for {@link TypeProviderImpl} class
*/
@Beta
final class TypeGenHelper {
private TypeGenHelper() {
throw new UnsupportedOperationException("Util class");
}
/**
* Gets base type definition for extendTypeDef
. The method is
* recursively called until non ExtendedType
type is found.
*
* @param extendTypeDef
* type definition for which is the base type definition sought
* @return type definition which is base type for extendTypeDef
* @throws IllegalArgumentException
* if extendTypeDef
equal null
*/
static TypeDefinition> baseTypeDefForExtendedType(final TypeDefinition> extendTypeDef) {
Preconditions.checkArgument(extendTypeDef != null, "Type Definition reference cannot be NULL!");
TypeDefinition> ret = extendTypeDef;
while (ret.getBaseType() != null) {
ret = ret.getBaseType();
}
return ret;
}
/**
* Creates generated TO with data about inner extended type
* innerExtendedType
, about the package name
* typedefName
and about the generated TO name
* typedefName
.
*
* It is supposed that innerExtendedType
is already present in
* {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} to
* be possible set it as extended type for the returning generated TO.
*
* @param typedef
* Type Definition
* @param innerExtendedType
* extended type which is part of some other extended type
* @param basePackageName
* string with the package name of the module
* @param moduleName
* Module Name
* @return generated TO which extends generated TO for
* innerExtendedType
* @throws IllegalArgumentException
*
extendedType
equals nullbasePackageName
equals nulltypedefName
equals nullType
to which is typedef
mapped
* @return generated transfer object which representjavaType
*/
static GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition> typedef, final Type javaType, final String moduleName) {
Preconditions.checkNotNull(javaType, "javaType cannot be null");
final String propertyName = "value";
final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef, moduleName);
genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef));
final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
genPropBuilder.setReturnType(javaType);
genTOBuilder.addEqualsIdentity(genPropBuilder);
genTOBuilder.addHashIdentity(genPropBuilder);
genTOBuilder.addToStringProperty(genPropBuilder);
if (typedef.getStatus() == Status.DEPRECATED) {
genTOBuilder.addAnnotation("", "Deprecated");
}
if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef.getBaseType() != null) {
final Listtypedef
to the list of
* the strings which represents these constraints.
*
* @param typedef
* extended type in which are the pattern constraints sought
* @return list of strings which represents the constraint patterns
* @throws IllegalArgumentException
* if typedef
equals null
*
*/
static ListgenTOBuilder
the constant which contains regular
* expressions from the regularExpressions
*
* @param genTOBuilder
* generated TO builder to which are
* regular expressions
added
* @param regularExpressions
* list of string which represent regular expressions
* @throws IllegalArgumentException
* genTOBuilder
equals nullregularExpressions
equals nullenumTypeDef
to
* {@link Enumeration
* enumeration}.
*
* @param enumTypeDef
* enumeration type definition which is converted to enumeration
* @param enumName
* string with name which is used as the enumeration name
* @return enumeration type which is built with data (name, enum values)
* from enumTypeDef
* @throws IllegalArgumentException
* enumTypeDef
equals nullenumTypeDef
equal nullenumTypeDef
equal nullenumTypeDef
equal nulltypedef
to the generated TO builder.
*
* @param basePackageName
* string with name of package to which the module belongs
* @param typedef
* type definition from which is the generated TO builder created
* @return generated TO builder which contains data from
* typedef
and basePackageName
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private static GeneratedTOBuilderImpl typedefToTransferObject(final String basePackageName, final TypeDefinition> typedef, final String moduleName) {
final String typeDefTOName = typedef.getQName().getLocalName();
if ((basePackageName != null) && (typeDefTOName != null)) {
final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(basePackageName, typeDefTOName);
final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
newType.setDescription(typedefDescription);
newType.setReference(typedef.getReference());
newType.setSchemaPath((List) typedef.getPath().getPathFromRoot());
newType.setModuleName(moduleName);
return newType;
}
return null;
}
static Module getParentModule(final SchemaNode node, final SchemaContext schemaContext) {
final QName qname = node.getPath().getPathFromRoot().iterator().next();
final URI namespace = qname.getNamespace();
final Date revision = qname.getRevision();
return schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
}
}