<artifactId>mockito-core</artifactId>
</dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-text</artifactId>
- </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
-import org.apache.commons.text.StringEscapeUtils;
import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext;
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;
*
* @param typedef
* extended type in which are the pattern constraints sought
- * @return list of strings which represents the constraint patterns
+ * @return map of strings which represents the constraint patterns
* @throws IllegalArgumentException
* if <code>typedef</code> equals null
*
*/
- static List<String> resolveRegExpressionsFromTypedef(final TypeDefinition<?> typedef) {
- Preconditions.checkArgument(typedef != null, "typedef can't be null");
-
- final List<PatternConstraint> patternConstraints;
- if (typedef instanceof StringTypeDefinition) {
- patternConstraints = ((StringTypeDefinition) typedef).getPatternConstraints();
- } else {
- patternConstraints = ImmutableList.of();
+ static Map<String, String> resolveRegExpressionsFromTypedef(final TypeDefinition<?> typedef) {
+ if (!(typedef instanceof StringTypeDefinition)) {
+ return ImmutableMap.of();
}
- final List<String> regExps = new ArrayList<>(patternConstraints.size());
- for (final PatternConstraint patternConstraint : patternConstraints) {
+ // TODO: run diff against base ?
+ final List<PatternConstraint> patternConstraints = ((StringTypeDefinition) typedef).getPatternConstraints();
+ final Map<String, String> regExps = Maps.newHashMapWithExpectedSize(patternConstraints.size());
+ for (PatternConstraint patternConstraint : patternConstraints) {
String regEx = patternConstraint.getJavaPatternString();
// The pattern can be inverted
regEx = applyModifier(optModifier.get(), regEx);
}
- final String modifiedRegEx = StringEscapeUtils.escapeJava(regEx);
- regExps.add(modifiedRegEx);
+ regExps.put(regEx, patternConstraint.getRegularExpressionString());
}
return regExps;
final List<TypeDefinition<?>> sortedTypeDefinition = new ArrayList<>();
final Map<Integer, List<TypeDefinition<?>>> typeDefinitionsDepths = new TreeMap<>();
- for (final TypeDefinition<?> unsortedTypeDefinition : unsortedTypeDefinitions) {
+ for (TypeDefinition<?> unsortedTypeDefinition : unsortedTypeDefinitions) {
final int depth = getTypeDefinitionDepth(unsortedTypeDefinition);
final List<TypeDefinition<?>> typeDefinitionsConcreteDepth = typeDefinitionsDepths.computeIfAbsent(depth, k -> new ArrayList<>());
typeDefinitionsConcreteDepth.add(unsortedTypeDefinition);
* @param genTOBuilder
* generated TO builder to which are
* <code>regular expressions</code> added
- * @param regularExpressions
+ * @param expressions
* list of string which represent regular expressions
- * @throws IllegalArgumentException
- * <ul>
- * <li>if <code>genTOBuilder</code> equals null</li>
- * <li>if <code>regularExpressions</code> equals null</li>
- * </ul>
*/
- static void addStringRegExAsConstant(final GeneratedTOBuilder genTOBuilder, final List<String> regularExpressions) {
- if (genTOBuilder == null) {
- throw new IllegalArgumentException("Generated transfer object builder can't be null");
- }
- if (regularExpressions == null) {
- throw new IllegalArgumentException("List of regular expressions can't be null");
- }
- if (!regularExpressions.isEmpty()) {
- genTOBuilder.addConstant(Types.listTypeFor(BaseYangTypes.STRING_TYPE), TypeConstants.PATTERN_CONSTANT_NAME,
- ImmutableList.copyOf(regularExpressions));
+ static void addStringRegExAsConstant(final GeneratedTOBuilder genTOBuilder, final Map<String, String> expressions) {
+ if (!expressions.isEmpty()) {
+ genTOBuilder.addConstant(Types.listTypeFor(BaseYangTypes.STRING_TYPE), BindingMapping.PATTERN_CONSTANT_NAME,
+ ImmutableMap.copyOf(expressions));
}
}
final List<TypeDefinition<?>> childTypeDefinitions = ((UnionTypeDefinition) baseType).getTypes();
int maxChildDepth = 0;
int childDepth = 1;
- for (final TypeDefinition<?> childTypeDefinition : childTypeDefinitions) {
+ for (TypeDefinition<?> childTypeDefinition : childTypeDefinitions) {
childDepth = childDepth + getTypeDefinitionDepth(childTypeDefinition);
if (childDepth > maxChildDepth) {
maxChildDepth = childDepth;
fillRecursively(ret, module);
final Set<NotificationDefinition> notifications = module.getNotifications();
- for (final NotificationDefinition notificationDefinition : notifications) {
+ for (NotificationDefinition notificationDefinition : notifications) {
fillRecursively(ret, notificationDefinition);
}
final Set<RpcDefinition> rpcs = module.getRpcs();
- for (final RpcDefinition rpcDefinition : rpcs) {
+ for (RpcDefinition rpcDefinition : rpcs) {
ret.addAll(rpcDefinition.getTypeDefinitions());
final ContainerSchemaNode input = rpcDefinition.getInput();
if (input != null) {
final Collection<DataSchemaNode> potentials = module.getChildNodes();
- for (final DataSchemaNode potential : potentials) {
+ for (DataSchemaNode potential : potentials) {
if (potential instanceof ActionNodeContainer) {
final Set<ActionDefinition> actions = ((ActionNodeContainer) potential).getActions();
- for (final ActionDefinition action: actions) {
+ for (ActionDefinition action: actions) {
final ContainerSchemaNode input = action.getInput();
if (input != null) {
fillRecursively(ret, input);
} else if (childNode instanceof ListSchemaNode) {
fillRecursively(list, (ListSchemaNode) childNode);
} else if (childNode instanceof ChoiceSchemaNode) {
- for (final CaseSchemaNode caseNode : ((ChoiceSchemaNode) childNode).getCases().values()) {
+ for (CaseSchemaNode caseNode : ((ChoiceSchemaNode) childNode).getCases().values()) {
fillRecursively(list, caseNode);
}
}
final Set<GroupingDefinition> groupings = container.getGroupings();
if (groupings != null) {
- for (final GroupingDefinition grouping : groupings) {
+ for (GroupingDefinition grouping : groupings) {
fillRecursively(list, grouping);
}
}
final String basePackageName = packageNameWithNamespacePrefix(getRootPackageName(module),
BindingNamespaceType.Typedef);
final List<TypeDefinition<?>> typeDefinitions = getAllTypedefs(module);
- final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
- if (listTypeDefinitions != null) {
- for (final TypeDefinition<?> typedef : listTypeDefinitions) {
- typedefToGeneratedType(basePackageName, module, typedef, genTypeDefsContextMap,
- additionalTypes, schemaContext, context);
- }
+ for (TypeDefinition<?> typedef : sortTypeDefinitionAccordingDepth(typeDefinitions)) {
+ typedefToGeneratedType(basePackageName, module, typedef, genTypeDefsContextMap,
+ additionalTypes, schemaContext, context);
}
});
}
* <li>if name of <code>typeDefinition</code></li>
* </ul>
*/
- public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode) {
+ public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition,
+ final SchemaNode parentNode) {
Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
"Type Definitions Local Name cannot be NULL!");
final Module module = findParentModule(this.schemaContext, parentNode);
if (module != null) {
- final Map<Optional<Revision>, Map<String, Type>> modulesByDate = this.genTypeDefsContextMap.get(module.getName());
+ final Map<Optional<Revision>, Map<String, Type>> modulesByDate =
+ this.genTypeDefsContextMap.get(module.getName());
final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
if (genTOs != null) {
return genTOs.get(typeDefinition.getQName().getLocalName());
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName,
- final TypeDefinition<?> typeDef, final String typeDefName, final String moduleName, final ModuleContext context) {
+ final TypeDefinition<?> typeDef, final String typeDefName, final String moduleName,
+ final ModuleContext context) {
Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");
Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
GeneratedPropertyBuilder genPropertyBuilder;
for (final Bit bit : bitList) {
final String name = bit.getName();
- genPropertyBuilder =
- genTOBuilder.addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(name, JavaIdentifier.METHOD));
+ genPropertyBuilder = genTOBuilder.addProperty(
+ JavaIdentifierNormalizer.normalizeSpecificIdentifier(name, JavaIdentifier.METHOD));
genPropertyBuilder.setReadOnly(true);
genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
@SuppressWarnings({ "rawtypes", "unchecked" })
public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode,
- final SchemaContext schemaContext, final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap, final ModuleContext context) {
+ final SchemaContext schemaContext,
+ final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
+ final ModuleContext context) {
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!");
generatedTOBuilders.add(unionGenTOBuilder);
unionGenTOBuilder.setIsUnion(true);
- final List<String> regularExpressions = new ArrayList<>();
+ final Map<String, String> expressions = new HashMap<>();
for (final TypeDefinition<?> unionType : unionTypes) {
final String unionTypeName = unionType.getQName().getLocalName();
if (unionType.getBaseType() != null) {
- resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, regularExpressions,
+ resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, expressions,
parentNode, schemaContext, genTypeDefsContextMap);
} else if (unionType instanceof UnionTypeDefinition) {
generatedTOBuilders.add(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionTypeDefinition) unionType,
updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
}
}
- if (!regularExpressions.isEmpty()) {
- addStringRegExAsConstant(unionGenTOBuilder, regularExpressions);
+ if (!expressions.isEmpty()) {
+ addStringRegExAsConstant(unionGenTOBuilder, expressions);
}
//storeGenTO(typedef, unionGenTOBuilder, parentNode);
private Type javaTypeForSchemaDefType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
final Restrictions r, final SchemaContext schemaContext,
- final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap, final ModuleContext context) {
+ final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
+ final ModuleContext context) {
Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
final String typedefName = typeDefinition.getQName().getLocalName();
Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!");
private Type typedefToGeneratedType(final String basePackageName, final Module module,
final TypeDefinition<?> typedef,
final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
- final Map<Module, Set<Type>> additionalTypes, final SchemaContext schemaContext, final ModuleContext context) {
+ final Map<Module, Set<Type>> additionalTypes, final SchemaContext schemaContext,
+ final ModuleContext context) {
final String moduleName = module.getName();
final Optional<Revision> moduleRevision = module.getRevision();
if (basePackageName != null && moduleName != null && typedef != null) {
* @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
*/
private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
- final SchemaContext schemaContext, final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
+ final SchemaContext schemaContext,
+ final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
final ModuleContext context) {
if (typeDefinition instanceof LeafrefTypeDefinition) {
final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
*
*/
public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode,
- final SchemaContext schemaContext, final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
+ final SchemaContext schemaContext,
+ final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
final ModuleContext context) {
-
Type returnType = null;
Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
* @return JAVA <code>Type</code> representation of <code>dataNode</code>
*/
private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode, final SchemaContext schemaContext,
- final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap, final ModuleContext context) {
+ final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
+ final ModuleContext context) {
Type returnType = null;
if (dataNode != null) {
if (dataNode instanceof LeafSchemaNode) {
* @return JAVA <code>Type</code> of the identity which is refrenced through
* <code>idref</code>
*/
- private static Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref, final SchemaContext schemaContext) {
+ private static Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref,
+ final SchemaContext schemaContext) {
//TODO: incompatibility with Binding spec v2, get first or only one
final QName baseIdQName = idref.getIdentities().iterator().next().getQName();
final Module module = schemaContext.findModule(baseIdQName.getModule()).orElse(null);
* string with name of property which should be added to
* <code>unionGentransObject</code>
*/
- private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) {
+ private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type,
+ final String propertyName) {
if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
final GeneratedPropertyBuilder propBuilder = unionGenTransObject
.addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(propertyName, JavaIdentifier.METHOD));
*/
private GeneratedTOBuilder resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
final UnionTypeDefinition unionSubtype, final String basePackageName, final SchemaNode parentNode,
- final SchemaContext schemaContext, final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
+ final SchemaContext schemaContext,
+ final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
final ModuleContext context) {
-
final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName());
final GeneratedTOBuilder subUnionGenTOBUilder = provideGeneratedTOBuilderForUnionTypeDef(
basePackageName, unionSubtype, newTOBuilderName, parentNode, schemaContext, genTypeDefsContextMap,
context);
final GeneratedPropertyBuilder propertyBuilder;
- propertyBuilder = parentUnionGenTOBuilder
- .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(newTOBuilderName, JavaIdentifier.METHOD));
+ propertyBuilder = parentUnionGenTOBuilder.addProperty(
+ JavaIdentifierNormalizer.normalizeSpecificIdentifier(newTOBuilderName, JavaIdentifier.METHOD));
propertyBuilder.setReturnType(subUnionGenTOBUilder);
parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
*/
public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode,
- final SchemaContext schemaContext, final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
+ final SchemaContext schemaContext,
+ final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
final ModuleContext context) {
final List<GeneratedTOBuilder> builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
* @param unionSubtype
* type definition of the <code>ExtendedType</code> type which
* represents union subtype
- * @param regularExpressions
- * list of strings with the regular expressions
+ * @param expressions
+ * map of strings with the regular expressions
* @param parentNode
* parent Schema Node for Extended Subtype
*
*/
private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
- final TypeDefinition<?> unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode,
- final SchemaContext schemaContext, final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap) {
-
+ final TypeDefinition<?> unionSubtype, final Map<String, String> expressions, final SchemaNode parentNode,
+ final SchemaContext schemaContext,
+ final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap) {
final String unionTypeName = unionSubtype.getQName().getLocalName();
final Type genTO = findGenTO(unionTypeName, unionSubtype, schemaContext, genTypeDefsContextMap);
if (genTO != null) {
updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, unionTypeName);
- } else {
- final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionSubtype);
- if (unionTypeName.equals(baseType.getQName().getLocalName())) {
- final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType,
- parentNode, null);
- if (javaType != null) {
- updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
- }
- } else if (baseType instanceof LeafrefTypeDefinition) {
- final Type javaType = javaTypeForSchemaDefinitionType(baseType,
- parentNode, null);
- boolean typeExist = false;
- for (final GeneratedPropertyBuilder generatedPropertyBuilder : parentUnionGenTOBuilder
- .getProperties()) {
- final Type origType = ((GeneratedPropertyBuilderImpl) generatedPropertyBuilder).getReturnType();
- if (origType != null && javaType != null && javaType == origType) {
- typeExist = true;
- break;
- }
- }
- if (!typeExist && javaType != null) {
- updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, new StringBuilder(javaType.getName())
- .append(parentUnionGenTOBuilder.getName()).append("Value").toString());
+ return;
+ }
+
+ final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionSubtype);
+ if (unionTypeName.equals(baseType.getQName().getLocalName())) {
+ final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType,
+ parentNode, null);
+ if (javaType != null) {
+ updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
+ }
+ } else if (baseType instanceof LeafrefTypeDefinition) {
+ final Type javaType = javaTypeForSchemaDefinitionType(baseType,
+ parentNode, null);
+ boolean typeExist = false;
+ for (final GeneratedPropertyBuilder generatedPropertyBuilder : parentUnionGenTOBuilder
+ .getProperties()) {
+ final Type origType = ((GeneratedPropertyBuilderImpl) generatedPropertyBuilder).getReturnType();
+ if (origType != null && javaType != null && javaType == origType) {
+ typeExist = true;
+ break;
}
}
- if (baseType instanceof StringTypeDefinition) {
- regularExpressions.addAll(resolveRegExpressionsFromTypedef(unionSubtype));
+ if (!typeExist && javaType != null) {
+ updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType,
+ javaType.getName() + parentUnionGenTOBuilder.getName() + "Value");
}
}
+ if (baseType instanceof StringTypeDefinition) {
+ expressions.putAll(resolveRegExpressionsFromTypedef(unionSubtype));
+ }
}
/**
+++ /dev/null
-/*
- * 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.util;
-
-import com.google.common.annotations.Beta;
-
-/**
- *
- * Contains constants used in relations with <code>Type</code>.
- */
-@Beta
-public final class TypeConstants {
-
- /**
- * Name of the class constant which hold list of the regular expression
- * strings.
- */
- public static final String PATTERN_CONSTANT_NAME = "PATTERN_CONSTANTS";
-
- /**
- * Creation of new instance is prohibited.
- */
- private TypeConstants() {
- }
-}
<artifactId>twirl-api_2.12</artifactId>
<version>1.3.13</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
return null;
}
+ //FIXME: this should be deprecated in favor of contantsTemplate
/**
* @param constant constant to emit
* @return string with constant wrapped in code
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
import org.opendaylight.mdsal.binding.javav2.spec.base.Item;
import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.CodeHelpers;
import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentable;
import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentation;
import org.opendaylight.mdsal.binding.javav2.spec.structural.AugmentationHolder;
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.common.QName;
public class BuilderRenderer extends BaseRenderer {
importedNames.put("instantiable", importedName(Instantiable.class));
importedNames.put("item", importedName(Item.class));
importedNames.put("identifiableItem", importedName(IdentifiableItem.class));
+ importedNames.put("qname", importedName(QName.class));
+ importedNames.put("codeHelpers", importedName(CodeHelpers.class));
+
if (getType().getParentType() != null) {
importedNames.put("parent", importedName(getType().getParentType()));
parentTypeForBuilderName = getType().getParentType().getFullyQualifiedName();
import static org.opendaylight.mdsal.binding.javav2.java.api.generator.util.TextTemplateUtil.fieldName;
import static org.opendaylight.mdsal.binding.javav2.java.api.generator.util.TextTemplateUtil.setterMethod;
-import static org.opendaylight.mdsal.binding.javav2.util.BindingMapping.MEMBER_PATTERN_LIST;
-import static org.opendaylight.mdsal.binding.javav2.util.BindingMapping.PATTERN_CONSTANT_NAME;
import com.google.common.base.Preconditions;
import com.google.common.collect.Collections2;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.regex.Pattern;
import org.opendaylight.mdsal.binding.javav2.java.api.generator.rangeGenerators.AbstractRangeGenerator;
import org.opendaylight.mdsal.binding.javav2.java.api.generator.rangeGenerators.LengthGenerator;
import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.classTemplate;
import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.classTemplateConstructors;
-import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.classTemplateInitBlock;
import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.classTemplateRestrictions;
import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.classTemplateUnionConstr;
+import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.constantsTemplate;
import org.opendaylight.mdsal.binding.javav2.model.api.Constant;
import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration;
import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedProperty;
import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType;
import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
import org.opendaylight.mdsal.binding.javav2.model.api.Type;
+import org.opendaylight.yangtools.yang.common.QName;
public class ClassRenderer extends BaseRenderer {
protected final GeneratedTransferObject genTO;
importedNames.put("lists", importedName(Lists.class));
importedNames.put("illegalArgumentException", importedName(IllegalArgumentException.class));
importedNames.put("boolean", importedName(Boolean.class));
+ importedNames.put("qname", importedName(QName.class));
final List<String> implementsListBuilder = new LinkedList<>();
if (!getType().getImplements().isEmpty()) {
}
final String enumerations = String.join("\n", enumList);
- final StringBuilder sb1 = new StringBuilder();
- final String initBlock = classTemplateInitBlock.render(importedName(Pattern.class)).body();
- if (!consts.isEmpty()) {
- for (Constant constant : consts) {
- if (PATTERN_CONSTANT_NAME.equals(constant.getName())) {
- if (constant.getValue() instanceof List<?>) {
- sb1.append("private static final ")
- .append(importedName(Pattern.class))
- .append("[] ")
- .append(MEMBER_PATTERN_LIST)
- .append(";\npublic static final ")
- .append(importedName(List.class))
- .append("<String> ")
- .append(PATTERN_CONSTANT_NAME)
- .append(" = ")
- .append(importedName(ImmutableList.class))
- .append(".of(");
- final List<String> constantList = new LinkedList<>();
- for (Object item : (List) constant.getValue()) {
- if (item instanceof String) {
- constantList.add("\"" + item + "\"");
- }
- }
- sb1.append(String.join(", ", constantList));
- sb1.append(");")
- .append(initBlock);
- }
- } else {
- sb1.append(emitConstant(constant));
- }
- }
- }
- final String constants = sb1.toString();
+ final String constants = constantsTemplate.render(getType(), importedNames, this::importedName).body();
if (genTO.getSuperType() != null) {
importedNames.put("superType", importedName(genTO.getSuperType()));
}
}
}
- if (!isValidArg) {
- throw new IllegalArgumentException(
- "expected one of: @{toListOfNames(getAllIfcs(genType.asInstanceOf[GeneratedType]))} \n" +
- "but was: " + arg
- );
- }
+
+ @{importedNames.get("codeHelpers")}.validValue(isValidArg, arg, "@{toListOfNames(getAllIfcs(genType.asInstanceOf[GeneratedType]))}");
}
}
}
}
}
-
@generateSetters() = {
@for(field <- properties) {
@if(!field.getReturnType.isInstanceOf[GeneratedType] && getRestrictions(field.getReturnType) != null) {
@if(addOverride) {@@Override}
public <E extends @{importedNames.get("augmentation")}<? super @{genType.getName}>> E get@{toFirstUpper(augmentField.getName)}
(@{importedNames.get("class")}<E> augmentationType) {
- if (augmentationType == null) {
- throw new IllegalArgumentException("Augmentation Type reference cannot be NULL!");
- }
- return (E) @{augmentField.getName}.get(augmentationType);
+ return (E) @{augmentField.getName}.get(@{importedNames.get("codeHelpers")}.nonNullValue(augmentationType, "augmentationType"));
}
}
}
@import org.opendaylight.mdsal.binding.javav2.java.api.generator.util.TextTemplateUtil.fieldName
@import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject
@import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedProperty
-@import org.opendaylight.mdsal.binding.javav2.util.BindingMapping.PATTERN_CONSTANT_NAME
+@import org.opendaylight.mdsal.binding.javav2.util.BindingMapping
@(genTo: GeneratedTransferObject, allProperties: List[GeneratedProperty], properties: List[GeneratedProperty],
parentProperties: List[GeneratedProperty], importedNames: Map[String, String], argumentsDeclaration: String,
@if(genTo.isTypedef && !allProperties.isEmpty && allProperties.size == 1 && allProperties.get(0).getName.equals("value")) {
@{importedNames.get("preconditions")}.checkNotNull(_value, "Supplied value may not be null");
@for(currentConstant <- genTo.getConstantDefinitions) {
- @if(PATTERN_CONSTANT_NAME.equals(currentConstant.getName) && currentConstant.getValue.isInstanceOf[List[_]]) {
- for (Pattern p : patterns) {
- @{importedNames.get("preconditions")}.checkArgument(p.matcher(_value).matches(), "Supplied value \"%s\" does not match required pattern \"%s\"", _value, p);
- }
+ @if(BindingMapping.PATTERN_CONSTANT_NAME.equals(currentConstant.getName)) {
+ @{importedNames.get("CodeHelpers")}.checkPattern(_value, @{BindingMapping.MEMBER_PATTERN_LIST}, @{BindingMapping.MEMBER_REGEX_LIST});
}
}
}
+++ /dev/null
-@*
- * Copyright (c) 2016 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
- *@
-
-@import org.opendaylight.mdsal.binding.javav2.util.BindingMapping.MEMBER_PATTERN_LIST
-@import org.opendaylight.mdsal.binding.javav2.util.BindingMapping.PATTERN_CONSTANT_NAME
-
-@(patterName: String)
-static {
- final @{patterName} a[] = new @{patterName}[@{PATTERN_CONSTANT_NAME}.size()];
- int i = 0;
- for (String regEx : @{PATTERN_CONSTANT_NAME}) {
- a[i++] = Pattern.compile(regEx);
- }
-
- @{MEMBER_PATTERN_LIST} = a;
-}
\ No newline at end of file
--- /dev/null
+@*
+ * Copyright (c) 2018 ZTE, 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
+ *@
+
+@import org.apache.commons.text.StringEscapeUtils.escapeJava
+@import org.opendaylight.mdsal.binding.javav2.model.api.Type
+@import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType
+@import org.opendaylight.mdsal.binding.javav2.model.api.Constant
+@import org.opendaylight.mdsal.binding.javav2.util.BindingMapping
+@import org.opendaylight.mdsal.binding.javav2.generator.util.Types
+@import org.opendaylight.yangtools.yang.common.QName;
+@import org.opendaylight.yangtools.yang.common.Revision;
+
+@(genType: GeneratedType, importedNames: Map[String, String], importedName: Function[Type, String])
+@for(c <- genType.getConstantDefinitions) {
+ @if(c.getName == BindingMapping.PATTERN_CONSTANT_NAME) {
+ @defining(c.getValue.asInstanceOf[Map[String, String]]) { cValue =>
+ public static final @{importedNames.get("list")}<@{importedNames.get("string")}> @{BindingMapping.PATTERN_CONSTANT_NAME} = @{importedNames.get("immutableList")}.of(
+ @{(cValue.keySet map {escapeJava}).mkString("\"", "\", \"", "\"")});
+ @if(cValue.size == 1) {
+ private static final @{importedNames.get("pattern")} @{BindingMapping.MEMBER_PATTERN_LIST} = @{importedNames.get("pattern")}.compile(@{BindingMapping.PATTERN_CONSTANT_NAME}.get(0));
+ private static final String @{BindingMapping.MEMBER_REGEX_LIST} = "@{escapeJava(cValue.values.stream.findFirst.get)}";
+ } else {
+ private static final @{importedNames.get("pattern")}[] @{BindingMapping.MEMBER_PATTERN_LIST} = @{importedNames.get("codeHelpers")}.compilePatterns(@{BindingMapping.PATTERN_CONSTANT_NAME});
+ private static final String[] @{BindingMapping.MEMBER_REGEX_LIST} = {
+ @{(cValue.keySet map {escapeJava}).mkString("\"", "\", \"", "\"")}
+ };
+ }
+ }
+ } else {
+ public static final @{importedName(c.getType())} @{c.getName} =
+ @if(c.getValue.isInstanceOf[QName]) {
+ @defining(c.getValue.asInstanceOf[QName]) { qname =>
+ @{importedNames.get("qname")}.create("@{qname.getNamespace}",
+ @defining(qname.getRevision()) { rev =>
+ @if(rev.isPresent()) {
+ "@{rev.get}"
+ } else {
+ "null";
+ }
+ }, "@{qname.getLocalName}").intern();
+ }
+ } else {
+ @{c.getValue};
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2018 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.spec.runtime;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verify;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.VerifyException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Helper methods for generated binding code. This class concentrates useful primitives generated code may call
+ * to perform specific shared functions. This allows for generated classes to be leaner. Methods in this class follows
+ * general API stability requirements of the Binding Specification.
+ *
+ * @author Robert Varga
+ */
+public final class CodeHelpers {
+ private static final String NEGATED_PATTERN_PREFIX = "^(?!";
+ private static final String NEGATED_PATTERN_SUFFIX = ").*$";
+
+ private CodeHelpers() {
+ // Hidden
+ }
+
+ /**
+ * Require that an a value-related expression is true.
+ *
+ * @param expression Expression to evaluate
+ * @param value Value being validated
+ * @param options Valid value options checked
+ * @throws IllegalArgumentException if expression is false
+ */
+ public static void validValue(final boolean expression, final Object value, final String options) {
+ checkArgument(expression, "expected one of: %s \n%but was: %s", options, value);
+ }
+
+ /**
+ * Require an argument being received. This is similar to {@link java.util.Objects#requireNonNull(Object)}, but
+ * throws an IllegalArgumentException.
+ *
+ * <p>
+ * Implementation note: we expect argName to be a string literal or a constant, so that it's non-nullness can be
+ * quickly discovered for a call site (where we are going to be inlined).
+ *
+ * @param value Value itself
+ * @param name Symbolic name
+ * @return non-null value
+ * @throws IllegalArgumentException if value is null
+ * @throws NullPointerException if name is null
+ */
+ // FIXME: another advantage is that it is JDT-annotated, but we could live without that. At some point we should
+ // schedule a big ISE-to-NPE conversion and just use Objects.requireNonNull() instead.
+ public static <T> @NonNull T nonNullValue(@Nullable final T value, final @NonNull String name) {
+ requireNonNull(name);
+ checkArgument(value != null, "%s must not be null", name);
+ return value;
+ }
+
+ /**
+ * Append a named value to a ToStringHelper. If the value is null, this method does nothing.
+ *
+ * @param helper Helper to append to
+ * @param name Name of the value
+ * @param value Value to append
+ * @throws NullPointerException if the name or helper is null
+ */
+ public static void appendValue(final @NonNull ToStringHelper helper, final @NonNull String name,
+ final @Nullable Object value) {
+ if (value != null) {
+ helper.add(name, value);
+ }
+ }
+
+ /**
+ * Append a named value to a ToStringHelper. If the value is null, this method does nothing.
+ *
+ * @param helper Helper to append to
+ * @param name Name of the value
+ * @param value Value to append
+ * @throws NullPointerException if the name or helper is null
+ */
+ public static void appendValue(final ToStringHelper helper, final String name, final byte[] value) {
+ if (value != null) {
+ helper.add(name, Arrays.toString(value));
+ }
+ }
+
+ /**
+ * Compile a list of pattern regular expressions and return them as an array. The list must hold at least two
+ * expressions.
+ *
+ * @param patterns Patterns to compile
+ * @return Compiled patterns in an array
+ * @throws NullPointerException if the list or any of its elements is null
+ * @throws VerifyException if the list has fewer than two elements
+ */
+ public static @NonNull Pattern[] compilePatterns(final @NonNull List<String> patterns) {
+ final int size = patterns.size();
+ verify(size > 1, "Patterns has to have at least 2 elements");
+ final @NonNull Pattern[] result = new Pattern[size];
+ for (int i = 0; i < size; ++i) {
+ result[i] = Pattern.compile(patterns.get(i));
+ }
+ return result;
+ }
+
+ /**
+ * Check whether a specified string value matches a specified pattern. This method handles the distinction between
+ * modeled XSD expression and enforcement {@link Pattern} which may reflect negation.
+ *
+ * @param value Value to be checked.
+ * @param pattern Enforcement pattern
+ * @param regex Source regular expression, as defined in YANG model
+ * @throws IllegalArgumentException if the value does not match the pattern
+ * @throws NullPointerException if any of the arguments are null
+ */
+ public static void checkPattern(final String value, final Pattern pattern, final String regex) {
+ if (!pattern.matcher(value).matches()) {
+ final String match = isNegatedPattern(pattern.toString()) ? "matches forbidden"
+ : "does not match required";
+ throw new IllegalArgumentException("Supplied value \"" + value + "\" " + match + " pattern \""
+ + regex + "\"");
+ }
+ }
+
+ private static boolean isNegatedPattern(final String pattern) {
+ return pattern.startsWith(NEGATED_PATTERN_PREFIX) && pattern.endsWith(NEGATED_PATTERN_SUFFIX);
+ }
+
+ /**
+ * Check whether a specified string value matches specified patterns. This method handles the distinction between
+ * modeled XSD expression and enforcement {@link Pattern} which may reflect negation.
+ *
+ * @param value Value to be checked.
+ * @param patterns Enforcement patterns
+ * @param regexes Source regular expression, as defined in YANG model. Size and order must match patterns.
+ * @throws IllegalArgumentException if the value does not match the pattern
+ * @throws NullPointerException if any of the arguments are null
+ * @throws VerifyException if the size of patterns and regexes does not match
+ */
+ public static void checkPattern(final String value, final Pattern[] patterns, final String[] regexes) {
+ verify(patterns.length == regexes.length, "Patterns and regular expression lengths have to match");
+ for (int i = 0; i < patterns.length; ++i) {
+ checkPattern(value, patterns[i], regexes[i]);
+ }
+ }
+
+ /**
+ * Throw an IllegalArgument exception describing a length violation.
+ *
+ * @param expected String describing expected lengths
+ * @param actual Actual observed object
+ * @throws IllegalArgumentException always
+ */
+ public static void throwInvalidLength(final String expected, final Object actual) {
+ throw new IllegalArgumentException("Invalid length: " + actual + ", expected: " + expected + ".");
+ }
+
+ /**
+ * Throw an IllegalArgument exception describing a length violation.
+ *
+ * @param expected String describing expected lengths
+ * @param actual Actual observed byte array
+ * @throws IllegalArgumentException always
+ */
+ public static void throwInvalidLength(final String expected, final byte[] actual) {
+ throwInvalidLength(expected, Arrays.toString(actual));
+ }
+
+ /**
+ * Throw an IllegalArgument exception describing a range violation.
+ *
+ * @param expected String describing expected ranges
+ * @param actual Actual observed object
+ * @throws IllegalArgumentException always
+ */
+ public static void throwInvalidRange(final String expected, final Object actual) {
+ throw new IllegalArgumentException("Invalid range: " + actual + ", expected: " + expected + ".");
+ }
+
+ /**
+ * Throw an IllegalArgument exception describing a range violation.
+ *
+ * @param expected Objects describing expected ranges
+ * @param actual Actual observed byte array
+ * @throws IllegalArgumentException always
+ */
+ public static void throwInvalidRange(final Object[] expected, final Object actual) {
+ throwInvalidRange(Arrays.toString(expected), actual);
+ }
+}
public static final String MODEL_BINDING_PROVIDER_CLASS_NAME = "$YangModelBindingProvider";
public static final String PATTERN_CONSTANT_NAME = "PATTERN_CONSTANTS";
public static final String MEMBER_PATTERN_LIST = "patterns";
+ public static final String MEMBER_REGEX_LIST = "regexes";
public static final String RPC_INPUT_SUFFIX = "Input";
public static final String RPC_OUTPUT_SUFFIX = "Output";