Bug 3067: Improved error reporting in Binding Data Codec
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / util / BindingRuntimeContext.java
index fe2510857f89911223c90a539e326c6e25f5e740..e92f1ca0d0562718b78effe222897276b3e2b12f 100644 (file)
@@ -26,6 +26,7 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
@@ -40,17 +41,17 @@ import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTy
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.AugmentationSchemaProxy;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
 import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -90,7 +91,7 @@ public class BindingRuntimeContext implements Immutable {
                 Preconditions.checkArgument(identityType != null, "Supplied QName %s is not a valid identity", key);
                 try {
                     return strategy.loadClass(identityType);
-                } catch (ClassNotFoundException e) {
+                } catch (final ClassNotFoundException e) {
                     throw new IllegalArgumentException("Required class " + identityType + "was not found.", e);
                 }
             }
@@ -100,11 +101,11 @@ public class BindingRuntimeContext implements Immutable {
         this.strategy = strategy;
         this.schemaContext = schema;
 
-        BindingGeneratorImpl generator = new BindingGeneratorImpl(false);
+        final BindingGeneratorImpl generator = new BindingGeneratorImpl(false);
         generator.generateTypes(schema);
-        Map<Module, ModuleContext> modules = generator.getModuleContexts();
+        final Map<Module, ModuleContext> modules = generator.getModuleContexts();
 
-        for (ModuleContext ctx : modules.values()) {
+        for (final ModuleContext ctx : modules.values()) {
             augmentationToSchema.putAll(ctx.getTypeToAugmentation());
             typeToDefiningSchema.putAll(ctx.getTypeToSchema());
 
@@ -163,14 +164,12 @@ public class BindingRuntimeContext implements Immutable {
      * schema.
      *
      * @param augClass Augmentation class
-     * @return Schema of augmentation
-     * @throws IllegalArgumentException If supplied class is not an augmentation or current context does not contain schema for augmentation.
+     * @return Schema of augmentation or null if augmentaiton is not known in this context
+     * @throws IllegalArgumentException If supplied class is not an augmentation
      */
-    public AugmentationSchema getAugmentationDefinition(final Class<?> augClass) throws IllegalArgumentException {
+    public @Nullable AugmentationSchema getAugmentationDefinition(final Class<?> augClass) throws IllegalArgumentException {
         Preconditions.checkArgument(Augmentation.class.isAssignableFrom(augClass), "Class %s does not represent augmentation", augClass);
-        final AugmentationSchema ret = augmentationToSchema.get(referencedType(augClass));
-        Preconditions.checkArgument(ret != null, "Supplied augmentation %s is not valid in current context", augClass);
-        return ret;
+        return augmentationToSchema.get(referencedType(augClass));
     }
 
     /**
@@ -194,7 +193,8 @@ public class BindingRuntimeContext implements Immutable {
 
     public Entry<AugmentationIdentifier, AugmentationSchema> getResolvedAugmentationSchema(final DataNodeContainer target,
             final Class<? extends Augmentation<?>> aug) {
-        AugmentationSchema origSchema = getAugmentationDefinition(aug);
+        final AugmentationSchema origSchema = getAugmentationDefinition(aug);
+        Preconditions.checkArgument(origSchema != null, "Augmentation %s is not known in current schema context",aug);
         /*
          * FIXME: Validate augmentation schema lookup
          *
@@ -207,15 +207,15 @@ public class BindingRuntimeContext implements Immutable {
          * with data and it is up to underlying user to validate data.
          *
          */
-        Set<QName> childNames = new HashSet<>();
-        Set<DataSchemaNode> realChilds = new HashSet<>();
-        for (DataSchemaNode child : origSchema.getChildNodes()) {
+        final Set<QName> childNames = new HashSet<>();
+        final Set<DataSchemaNode> realChilds = new HashSet<>();
+        for (final DataSchemaNode child : origSchema.getChildNodes()) {
             realChilds.add(target.getDataChildByName(child.getQName()));
             childNames.add(child.getQName());
         }
 
-        AugmentationIdentifier identifier = new AugmentationIdentifier(childNames);
-        AugmentationSchema proxy = new AugmentationSchemaProxy(origSchema, realChilds);
+        final AugmentationIdentifier identifier = new AugmentationIdentifier(childNames);
+        final AugmentationSchema proxy = new EffectiveAugmentationSchema(origSchema, realChilds);
         return new AbstractMap.SimpleEntry<>(identifier, proxy);
     }
 
@@ -229,8 +229,8 @@ public class BindingRuntimeContext implements Immutable {
      *         the given context.
      * @throws IllegalArgumentException If supplied class does not represent case.
      */
-    public Optional<ChoiceCaseNode> getCaseSchemaDefinition(final ChoiceNode schema, final Class<?> childClass) throws IllegalArgumentException {
-        DataSchemaNode origSchema = getSchemaDefinition(childClass);
+    public Optional<ChoiceCaseNode> getCaseSchemaDefinition(final ChoiceSchemaNode schema, final Class<?> childClass) throws IllegalArgumentException {
+        final DataSchemaNode origSchema = getSchemaDefinition(childClass);
         Preconditions.checkArgument(origSchema instanceof ChoiceCaseNode, "Supplied schema %s is not case.", origSchema);
 
         /* FIXME: Make sure that if there are multiple augmentations of same
@@ -260,8 +260,8 @@ public class BindingRuntimeContext implements Immutable {
      *     which was used to generate supplied class.
      */
     public Entry<GeneratedType, Object> getTypeWithSchema(final Class<?> type) {
-        Object schema = typeToDefiningSchema.get(referencedType(type));
-        Type definedType = typeToDefiningSchema.inverse().get(schema);
+        final Object schema = typeToDefiningSchema.get(referencedType(type));
+        final Type definedType = typeToDefiningSchema.inverse().get(schema);
         Preconditions.checkNotNull(schema);
         Preconditions.checkNotNull(definedType);
         if(definedType instanceof GeneratedTypeBuilder) {
@@ -273,20 +273,20 @@ public class BindingRuntimeContext implements Immutable {
     }
 
     public ImmutableMap<Type, Entry<Type, Type>> getChoiceCaseChildren(final DataNodeContainer schema) {
-        Map<Type,Entry<Type,Type>> childToCase = new HashMap<>();;
-        for (ChoiceNode choice :  FluentIterable.from(schema.getChildNodes()).filter(ChoiceNode.class)) {
-            ChoiceNode originalChoice = getOriginalSchema(choice);
-            Type choiceType = referencedType(typeToDefiningSchema.inverse().get(originalChoice));
-            Collection<Type> cases = choiceToCases.get(choiceType);
+        final Map<Type,Entry<Type,Type>> childToCase = new HashMap<>();
+        for (final ChoiceSchemaNode choice :  FluentIterable.from(schema.getChildNodes()).filter(ChoiceSchemaNode.class)) {
+            final ChoiceSchemaNode originalChoice = getOriginalSchema(choice);
+            final Type choiceType = referencedType(typeToDefiningSchema.inverse().get(originalChoice));
+            final Collection<Type> cases = choiceToCases.get(choiceType);
 
             for (Type caze : cases) {
-                Entry<Type,Type> caseIdentifier = new SimpleEntry<>(choiceType,caze);
-                HashSet<Type> caseChildren = new HashSet<>();
+                final Entry<Type,Type> caseIdentifier = new SimpleEntry<>(choiceType,caze);
+                final HashSet<Type> caseChildren = new HashSet<>();
                 if (caze instanceof GeneratedTypeBuilder) {
                     caze = ((GeneratedTypeBuilder) caze).toInstance();
                 }
                 collectAllContainerTypes((GeneratedType) caze, caseChildren);
-                for (Type caseChild : caseChildren) {
+                for (final Type caseChild : caseChildren) {
                     childToCase.put(caseChild, caseIdentifier);
                 }
             }
@@ -295,25 +295,25 @@ public class BindingRuntimeContext implements Immutable {
     }
 
     public Set<Class<?>> getCases(final Class<?> choice) {
-        Collection<Type> cazes = choiceToCases.get(referencedType(choice));
-        Set<Class<?>> ret = new HashSet<>(cazes.size());
-        for(Type caze : cazes) {
+        final Collection<Type> cazes = choiceToCases.get(referencedType(choice));
+        final Set<Class<?>> ret = new HashSet<>(cazes.size());
+        for(final Type caze : cazes) {
             try {
                 final Class<?> c = strategy.loadClass(caze);
                 ret.add(c);
-            } catch (ClassNotFoundException e) {
+            } catch (final ClassNotFoundException e) {
                 LOG.warn("Failed to load class for case {}, ignoring it", caze, e);
             }
         }
         return ret;
     }
 
-    public Class<?> getClassForSchema(final DataSchemaNode childSchema) {
-        DataSchemaNode origSchema = getOriginalSchema(childSchema);
-        Type clazzType = typeToDefiningSchema.inverse().get(origSchema);
+    public Class<?> getClassForSchema(final SchemaNode childSchema) {
+        final SchemaNode origSchema = getOriginalSchema(childSchema);
+        final Type clazzType = typeToDefiningSchema.inverse().get(origSchema);
         try {
             return strategy.loadClass(clazzType);
-        } catch (ClassNotFoundException e) {
+        } catch (final ClassNotFoundException e) {
             throw new IllegalStateException(e);
         }
     }
@@ -321,8 +321,8 @@ public class BindingRuntimeContext implements Immutable {
     public ImmutableMap<AugmentationIdentifier,Type> getAvailableAugmentationTypes(final DataNodeContainer container) {
         final Map<AugmentationIdentifier,Type> identifierToType = new HashMap<>();
         if (container instanceof AugmentationTarget) {
-            Set<AugmentationSchema> augments = ((AugmentationTarget) container).getAvailableAugmentations();
-            for (AugmentationSchema augment : augments) {
+            final Set<AugmentationSchema> augments = ((AugmentationTarget) container).getAvailableAugmentations();
+            for (final AugmentationSchema augment : augments) {
                 // Augmentation must have child nodes if is to be used with Binding classes
                 AugmentationSchema augOrig = augment;
                 while (augOrig.getOriginalDefinition().isPresent()) {
@@ -330,7 +330,7 @@ public class BindingRuntimeContext implements Immutable {
                 }
 
                 if (!augment.getChildNodes().isEmpty()) {
-                    Type augType = typeToDefiningSchema.inverse().get(augOrig);
+                    final Type augType = typeToDefiningSchema.inverse().get(augOrig);
                     if (augType != null) {
                         identifierToType.put(getAugmentationIdentifier(augment),augType);
                     }
@@ -342,8 +342,8 @@ public class BindingRuntimeContext implements Immutable {
     }
 
     private AugmentationIdentifier getAugmentationIdentifier(final AugmentationSchema augment) {
-        Set<QName> childNames = new HashSet<>();
-        for (DataSchemaNode child : augment.getChildNodes()) {
+        final Set<QName> childNames = new HashSet<>();
+        for (final DataSchemaNode child : augment.getChildNodes()) {
             childNames.add(child.getQName());
         }
         return new AugmentationIdentifier(childNames);
@@ -357,7 +357,7 @@ public class BindingRuntimeContext implements Immutable {
     }
 
     private static Set<Type> collectAllContainerTypes(final GeneratedType type, final Set<Type> collection) {
-        for (MethodSignature definition : type.getMethodDefinitions()) {
+        for (final MethodSignature definition : type.getMethodDefinitions()) {
             Type childType = definition.getReturnType();
             if(childType instanceof ParameterizedType) {
                 childType = ((ParameterizedType) childType).getActualTypeArguments()[0];
@@ -366,7 +366,7 @@ public class BindingRuntimeContext implements Immutable {
                 collection.add(referencedType(childType));
             }
         }
-        for (Type parent : type.getImplements()) {
+        for (final Type parent : type.getImplements()) {
             if (parent instanceof GeneratedType) {
                 collectAllContainerTypes((GeneratedType) parent, collection);
             }
@@ -376,7 +376,7 @@ public class BindingRuntimeContext implements Immutable {
 
     private static final <T extends SchemaNode> T getOriginalSchema(final T choice) {
         @SuppressWarnings("unchecked")
-        T original = (T) SchemaNodeUtils.getRootOriginalIfPossible(choice);
+        final T original = (T) SchemaNodeUtils.getRootOriginalIfPossible(choice);
         if (original != null) {
             return original;
         }