Do not use BindingReflections in IdentityCodec
[yangtools.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / IdentityCodec.java
index 1297b0ddc9da90d7ab9a829b1ab6b61c22ed1893..3fa1a9c03562da03cc048f9906ba2a39648b3f86 100644 (file)
@@ -19,13 +19,12 @@ import java.util.concurrent.ExecutionException;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingIdentityCodec;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
-import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
-import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.yangtools.concepts.AbstractIllegalArgumentCodec;
+import org.opendaylight.mdsal.binding.runtime.api.IdentityRuntimeType;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yangtools.yang.binding.contract.Naming;
 import org.opendaylight.yangtools.yang.common.QName;
 
-final class IdentityCodec extends AbstractIllegalArgumentCodec<QName, BaseIdentity> implements BindingIdentityCodec {
+final class IdentityCodec extends AbstractValueCodec<QName, BaseIdentity> implements BindingIdentityCodec {
     private final LoadingCache<@NonNull QName, @NonNull BaseIdentity> values = CacheBuilder.newBuilder()
         .build(new CacheLoader<>() {
             @Override
@@ -33,10 +32,10 @@ final class IdentityCodec extends AbstractIllegalArgumentCodec<QName, BaseIdenti
                 final var clazz = context.getIdentityClass(key);
                 final Field field;
                 try {
-                    field = clazz.getField(BindingMapping.VALUE_STATIC_FIELD_NAME);
+                    field = clazz.getField(Naming.VALUE_STATIC_FIELD_NAME);
                 } catch (NoSuchFieldException e) {
-                    throw new LinkageError(clazz + " does not define required field "
-                        + BindingMapping.VALUE_STATIC_FIELD_NAME, e);
+                    throw new LinkageError(clazz + " does not define required field " + Naming.VALUE_STATIC_FIELD_NAME,
+                        e);
                 }
                 if (!Modifier.isStatic(field.getModifiers())) {
                     throw new LinkageError(field + " is not static");
@@ -58,6 +57,18 @@ final class IdentityCodec extends AbstractIllegalArgumentCodec<QName, BaseIdenti
                 }
             }
         });
+    private final LoadingCache<@NonNull Class<? extends BaseIdentity>, @NonNull QName> qnames =
+        // Note: weak keys because it is the user who is supplying implemented contract
+        CacheBuilder.newBuilder().weakKeys().build(new CacheLoader<>() {
+            @Override
+            public QName load(final Class<? extends BaseIdentity> key) {
+                final var schema = context.getTypeWithSchema(key);
+                if (schema instanceof IdentityRuntimeType identitySchema) {
+                    return identitySchema.statement().argument();
+                }
+                throw new IllegalStateException("Unexpected schema " + schema + " for " + key);
+            }
+        });
 
     private final BindingRuntimeContext context;
 
@@ -88,6 +99,11 @@ final class IdentityCodec extends AbstractIllegalArgumentCodec<QName, BaseIdenti
 
     @Override
     public QName fromBinding(final BaseIdentity bindingValue) {
-        return BindingReflections.getQName(bindingValue.implementedInterface());
+        try {
+            return qnames.get(bindingValue.implementedInterface());
+        } catch (ExecutionException e) {
+            Throwables.throwIfUnchecked(e.getCause());
+            throw new IllegalStateException("Unexpected error translating " + bindingValue, e);
+        }
     }
 }