BUG-981: force callers to handle exceptions 79/6879/8
authorRobert Varga <rovarga@cisco.com>
Sun, 11 May 2014 16:01:35 +0000 (18:01 +0200)
committerRobert Varga <rovarga@cisco.com>
Sun, 11 May 2014 20:33:13 +0000 (22:33 +0200)
This patch makes sure all the callsites acknowledge that the
transformer generator may fail. Also introduces proper chaining so we do
not lose information.

Change-Id: Ifce672b52a4f9d07104778f4e5060f51804747cc
Signed-off-by: Robert Varga <rovarga@cisco.com>
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/AbstractTransformerGenerator.java
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/LazyGeneratedCodecRegistry.java
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/TransformerGenerator.xtend
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/TransformerGeneratorException.java [new file with mode: 0644]

index eb047955a91d741a3c41111d16e079793242573d..fd280427d41b978c847e301da669b29e9010afc7 100644 (file)
@@ -85,28 +85,66 @@ abstract class AbstractTransformerGenerator {
         }
     }
 
-    private static final Map<SchemaPath, InstanceIdentifier<?>> pathToBindingIdentifier = new ConcurrentHashMap<>();
-
     protected final InstanceIdentifier<?> getBindingIdentifierByPath(final SchemaPath path) {
-        return pathToBindingIdentifier.get(path);
+        return PATH_TO_BINDING_IDENTIFIER.get(path);
     }
 
     protected final void putPathToBindingIdentifier(final SchemaPath path, final InstanceIdentifier<?> bindingIdentifier) {
-        pathToBindingIdentifier.put(path, bindingIdentifier);
+        PATH_TO_BINDING_IDENTIFIER.put(path, bindingIdentifier);
     }
 
     protected final InstanceIdentifier<?> putPathToBindingIdentifier(final SchemaPath path,
             final InstanceIdentifier<?> bindingIdentifier, final Class<?> childClass) {
         @SuppressWarnings({ "unchecked", "rawtypes" })
         InstanceIdentifier<?> newId = bindingIdentifier.builder().child((Class) childClass).build();
-        pathToBindingIdentifier.put(path, newId);
+        PATH_TO_BINDING_IDENTIFIER.put(path, newId);
         return newId;
     }
 
+    protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerForImpl(Class<?> inputType);
+    protected abstract Class<? extends BindingCodec<Object, Object>> caseCodecForImpl(Class<?> inputType, ChoiceCaseNode node);
+    protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiableImpl(Class<?> parentType);
+    protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifierImpl(Class<?> inputType);
+    protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerForImpl(Class<?> inputType);
+
     // Called from LazyGeneratedCodecRegistry
-    abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType);
-    abstract Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node);
-    abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType);
-    abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class<?> inputType);
-    abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType);
+    final Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(final Class<?> inputType) throws TransformerGeneratorException {
+        try {
+            return augmentationTransformerForImpl(inputType);
+        } catch (Exception e) {
+            throw TransformerGeneratorException.wrap(inputType, e);
+        }
+    }
+
+    final Class<? extends BindingCodec<Object, Object>> caseCodecFor(final Class<?> inputType, final ChoiceCaseNode node) throws TransformerGeneratorException {
+        try {
+            return caseCodecForImpl(inputType, node);
+        } catch (Exception e) {
+            throw TransformerGeneratorException.wrap(inputType, e);
+        }
+    }
+
+    final Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(final Class<?> parentType) throws TransformerGeneratorException {
+        try {
+            return keyTransformerForIdentifiableImpl(parentType);
+        } catch (Exception e) {
+            throw TransformerGeneratorException.wrap(parentType, e);
+        }
+    }
+
+    final Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(final Class<?> inputType) throws TransformerGeneratorException {
+        try {
+            return keyTransformerForIdentifierImpl(inputType);
+        } catch (Exception e) {
+            throw TransformerGeneratorException.wrap(inputType, e);
+        }
+    }
+
+    final Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(final Class<?> inputType) throws TransformerGeneratorException {
+        try {
+            return transformerForImpl(inputType);
+        } catch (Exception e) {
+            throw TransformerGeneratorException.wrap(inputType, e);
+        }
+    }
 }
index edc186e0ebe0dbe5aabd5305502508f0a2abae6d..28027f025939936491c67f23ed13737ccac0fe44 100644 (file)
@@ -158,21 +158,13 @@ class LazyGeneratedCodecRegistry implements //
         if (potentialCodec != null) {
             codec = potentialCodec;
         } else {
-            try {
-                lock.waitForSchema(object);
-                Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentRawCodec = generator
-                        .augmentationTransformerFor(object);
-                BindingCodec<Map<QName, Object>, Object> rawCodec = augmentRawCodec.newInstance();
-
-                codec = new AugmentationCodecWrapper<T>(rawCodec, null, object);
-                augmentationCodecs.put(object, codec);
-            } catch (InstantiationException e) {
-                LOG.error("Can not instantiate raw augmentation codec {}", object.getSimpleName(), e);
-            } catch (IllegalAccessException e) {
-                LOG.debug(
-                        "Run-time consistency issue: constructor {} is not available. This indicates either a code generation bug or a misconfiguration of JVM.",
-                        object.getSimpleName(), e);
-            }
+            lock.waitForSchema(object);
+            Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentRawCodec = generator
+                    .augmentationTransformerFor(object);
+
+            BindingCodec<Map<QName, Object>, Object> rawCodec = newInstanceOf(augmentRawCodec);
+            codec = new AugmentationCodecWrapper<T>(rawCodec, null, object);
+            augmentationCodecs.put(object, codec);
         }
         Class<? extends Augmentable<?>> objectSupertype = getAugmentableArgumentFrom(object);
         if (objectSupertype != null) {
@@ -328,15 +320,18 @@ class LazyGeneratedCodecRegistry implements //
         return null;
     }
 
-    private <T> T newInstanceOf(final Class<?> newType) {
+    private static <T> T newInstanceOf(final Class<?> cls) {
         try {
             @SuppressWarnings("unchecked")
-            T ret = (T) newType.newInstance();
+            T ret = (T) cls.newInstance();
             return ret;
         } catch (InstantiationException e) {
-            throw new IllegalStateException(e);
+            LOG.error("Failed to instantiate codec {}", cls.getSimpleName(), e);
+            throw new IllegalStateException(String.format("Failed to instantiate codec %s", cls), e);
         } catch (IllegalAccessException e) {
-            throw new IllegalStateException(e);
+            LOG.debug("Run-time consistency issue: constructor for {} is not available. This indicates either a code generation bug or a misconfiguration of JVM.",
+                    cls.getSimpleName(), e);
+            throw new IllegalStateException(String.format("Cannot access contructor of %s", cls), e);
         }
     }
 
index 04ce10a72e358f39d61da7128a1fd7bd5b3d12c8..b0a5c2b5a12677019ece3b2c2001d74d627445ed 100644 (file)
@@ -96,7 +96,7 @@ class TransformerGenerator extends AbstractTransformerGenerator {
         ctQName = QName.asCtClass
     }
 
-    override Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class inputType) {
+    override transformerForImpl(Class inputType) {
         return runOnClassLoader(inputType.classLoader) [ |
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
@@ -137,7 +137,7 @@ class TransformerGenerator extends AbstractTransformerGenerator {
         ]
     }
 
-    override Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class inputType) {
+    override augmentationTransformerForImpl(Class inputType) {
         return runOnClassLoader(inputType.classLoader) [ |
 
             val ret = getGeneratedClass(inputType)
@@ -155,7 +155,7 @@ class TransformerGenerator extends AbstractTransformerGenerator {
         ]
     }
 
-    override Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class inputType, ChoiceCaseNode node) {
+    override caseCodecForImpl(Class inputType, ChoiceCaseNode node) {
         return runOnClassLoader(inputType.classLoader) [ |
             createMapping(inputType, node, null)
             val ret = getGeneratedClass(inputType)
@@ -170,7 +170,7 @@ class TransformerGenerator extends AbstractTransformerGenerator {
         ]
     }
 
-    override Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class parentType) {
+    override keyTransformerForIdentifiableImpl(Class parentType) {
         return runOnClassLoader(parentType.classLoader) [ |
             val inputName = parentType.name + "Key";
             val inputType = loadClass(inputName);
@@ -249,7 +249,7 @@ class TransformerGenerator extends AbstractTransformerGenerator {
         return keyMethod.returnType as GeneratedTransferObject
     }
 
-    override Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class inputType) {
+    override keyTransformerForIdentifierImpl(Class inputType) {
         return runOnClassLoader(inputType.classLoader) [ |
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/TransformerGeneratorException.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/TransformerGeneratorException.java
new file mode 100644 (file)
index 0000000..1b160f0
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 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.yangtools.sal.binding.generator.impl;
+
+final class TransformerGeneratorException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    public TransformerGeneratorException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+    public static TransformerGeneratorException wrap(final Class<?> cls, final Throwable cause) throws TransformerGeneratorException {
+        return new TransformerGeneratorException(String.format("Failed to generate for type %s", cls), cause);
+    }
+}