BUG-981: untangle interfaces
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / LazyGeneratedCodecRegistry.java
index e2a01a2fcf79ac6e662091323bccb33f2baab4ad..edc186e0ebe0dbe5aabd5305502508f0a2abae6d 100644 (file)
@@ -81,18 +81,13 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
 
-public class LazyGeneratedCodecRegistry implements //
+class LazyGeneratedCodecRegistry implements //
         CodecRegistry, //
         SchemaContextListener, //
         GeneratorListener {
 
-    private final static Logger LOG = LoggerFactory.getLogger(LazyGeneratedCodecRegistry.class);
-    private final static LateMixinCodec NOT_READY_CODEC = new LateMixinCodec();
-
-    private final InstanceIdentifierCodec instanceIdentifierCodec = new InstanceIdentifierCodecImpl(this);
-    private final IdentityCompositeCodec identityRefCodec = new IdentityCompositeCodec();
-
-    private TransformerGenerator generator;
+    private static final Logger LOG = LoggerFactory.getLogger(LazyGeneratedCodecRegistry.class);
+    private static final LateMixinCodec NOT_READY_CODEC = new LateMixinCodec();
 
     // Concrete class to codecs
     private static final Map<Class<?>, DataContainerCodec<?>> containerCodecs = Collections
@@ -117,9 +112,6 @@ public class LazyGeneratedCodecRegistry implements //
     @SuppressWarnings("rawtypes")
     private static final ConcurrentMap<Type, ChoiceCaseCodecImpl> typeToCaseCodecs = new ConcurrentHashMap<>();
 
-    private final CaseClassMapFacade classToCaseRawCodec = new CaseClassMapFacade();
-
-    private static final Map<SchemaPath, InstanceIdentifier<?>> pathToBindingIdentifier = new ConcurrentHashMap<>();
     private static final Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap<>();
     private static final Map<List<QName>, Type> pathToInstantiatedType = new ConcurrentHashMap<>();
     private static final Map<Type, QName> typeToQname = new ConcurrentHashMap<>();
@@ -131,29 +123,27 @@ public class LazyGeneratedCodecRegistry implements //
     private static final Multimap<Type, Type> choiceToCases = Multimaps.synchronizedMultimap(HashMultimap
             .<Type, Type> create());
 
+    private final InstanceIdentifierCodec instanceIdentifierCodec = new InstanceIdentifierCodecImpl(this);
+    private final CaseClassMapFacade classToCaseRawCodec = new CaseClassMapFacade();
+    private final IdentityCompositeCodec identityRefCodec = new IdentityCompositeCodec();
+    private final ClassLoadingStrategy classLoadingStrategy;
+    private final AbstractTransformerGenerator generator;
     private final SchemaLock lock;
 
+    // FIXME: how is this protected?
     private SchemaContext currentSchema;
 
-    private final ClassLoadingStrategy classLoadingStrategy;
-
-    LazyGeneratedCodecRegistry(final SchemaLock lock, final ClassLoadingStrategy identityClassLoadingStrategy) {
+    LazyGeneratedCodecRegistry(final SchemaLock lock, final AbstractTransformerGenerator generator,
+            final ClassLoadingStrategy classLoadingStrategy) {
         this.lock = Preconditions.checkNotNull(lock);
-        this.classLoadingStrategy = identityClassLoadingStrategy;
+        this.classLoadingStrategy = Preconditions.checkNotNull(classLoadingStrategy);
+        this.generator = Preconditions.checkNotNull(generator);
     }
 
     public SchemaLock getLock() {
         return lock;
     }
 
-    public TransformerGenerator getGenerator() {
-        return generator;
-    }
-
-    public void setGenerator(final TransformerGenerator generator) {
-        this.generator = generator;
-    }
-
     @Override
     public InstanceIdentifierCodec getInstanceIdentifierCodec() {
         return instanceIdentifierCodec;
@@ -167,7 +157,7 @@ public class LazyGeneratedCodecRegistry implements //
         AugmentationCodecWrapper potentialCodec = augmentationCodecs.get(object);
         if (potentialCodec != null) {
             codec = potentialCodec;
-        } else
+        } else {
             try {
                 lock.waitForSchema(object);
                 Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentRawCodec = generator
@@ -183,6 +173,7 @@ public class LazyGeneratedCodecRegistry implements //
                         "Run-time consistency issue: constructor {} is not available. This indicates either a code generation bug or a misconfiguration of JVM.",
                         object.getSimpleName(), e);
             }
+        }
         Class<? extends Augmentable<?>> objectSupertype = getAugmentableArgumentFrom(object);
         if (objectSupertype != null) {
             getAugmentableCodec(objectSupertype).addImplementation(codec);
@@ -213,45 +204,32 @@ public class LazyGeneratedCodecRegistry implements //
 
     @Override
     public Class<?> getClassForPath(final List<QName> names) {
-        DataSchemaNode node = getSchemaNode(names);
-        SchemaPath path = node.getPath();
-        Type type = pathToType.get(path);
-        if (type != null) {
-            type = new ReferencedTypeImpl(type.getPackageName(), type.getName());
+        final DataSchemaNode node = getSchemaNode(names);
+        final SchemaPath path = node.getPath();
+        final Type t = pathToType.get(path);
+
+        final Type type;
+        if (t != null) {
+            type = new ReferencedTypeImpl(t.getPackageName(), t.getName());
         } else {
             type = pathToInstantiatedType.get(names);
-        }
-        @SuppressWarnings("rawtypes")
-        WeakReference<Class> weakRef = typeToClass.get(type);
-        if (weakRef == null) {
-            LOG.error("Could not find loaded class for path: {} and type: {}", path, type.getFullyQualifiedName());
+            Preconditions.checkState(type != null, "Failed to lookup instantiated type for path %s", path);
         }
 
+        @SuppressWarnings("rawtypes")
+        final WeakReference<Class> weakRef = typeToClass.get(type);
+        Preconditions.checkState(weakRef != null, "Could not find loaded class for path: %s and type: %s", path, type.getFullyQualifiedName());
         return weakRef.get();
     }
 
     @Override
     public void putPathToClass(final List<QName> names, final Class<?> cls) {
-        Type reference = Types.typeForClass(cls);
+        final Type reference = Types.typeForClass(cls);
         pathToInstantiatedType.put(names, reference);
+        LOG.trace("Path {} attached to class {} reference {}", names, cls, reference);
         bindingClassEncountered(cls);
     }
 
-    public InstanceIdentifier<?> getBindingIdentifierByPath(final SchemaPath path) {
-        return pathToBindingIdentifier.get(path);
-    }
-
-    public void putPathToBindingIdentifier(final SchemaPath path, final InstanceIdentifier<?> bindingIdentifier) {
-        pathToBindingIdentifier.put(path, bindingIdentifier);
-    }
-
-    public InstanceIdentifier<?> putPathToBindingIdentifier(final SchemaPath path,
-            final InstanceIdentifier<?> bindingIdentifier, final Class<?> childClass) {
-        InstanceIdentifier<?> newId = bindingIdentifier.builder().child((Class) childClass).build();
-        pathToBindingIdentifier.put(path, newId);
-        return newId;
-    }
-
     @Override
     public IdentifierCodec<?> getKeyCodecForPath(final List<QName> names) {
         @SuppressWarnings("unchecked")
@@ -424,7 +402,6 @@ public class LazyGeneratedCodecRegistry implements //
                 caseClass.getName());
         Preconditions.checkState(caseCodec.getSchema() != null, "Case schema is not available for %s",
                 caseClass.getName());
-        @SuppressWarnings("unchecked")
         Class<? extends BindingCodec> newCodec = generator.caseCodecFor(caseClass, caseCodec.getSchema());
         BindingCodec newInstance = newInstanceOf(newCodec);
         caseCodec.setDelegate(newInstance);
@@ -709,10 +686,35 @@ public class LazyGeneratedCodecRegistry implements //
             if (adaptedForPaths.contains(path)) {
                 return;
             }
+            /**
+             * We search in schema context if the use of this location aware codec (augmentable codec, case codec)
+             * makes sense on provided location (path)
+             *
+             */
             Optional<DataNodeContainer> contextNode = BindingSchemaContextUtils.findDataNodeContainer(currentSchema, path);
+            /**
+             * If context node is present, this codec makes sense on provided location.
+             *
+             */
             if (contextNode.isPresent()) {
                 synchronized (this) {
+                    /**
+                     *
+                     * We adapt (turn on / off) possible implementations of child codecs (augmentations, cases)
+                     * based on this location.
+                     *
+                     *
+                     */
                     adaptForPathImpl(path, contextNode.get());
+                    try  {
+                        /**
+                         * We trigger serialization of instance identifier, to make sure instance identifier
+                         * codec is aware of combination of this path / augmentation / case
+                         */
+                        instanceIdentifierCodec.serialize(path);
+                    } catch (Exception e) {
+                        LOG.warn("Exception during preparation of instance identifier codec for  path {}.",path,e);
+                    }
                     adaptedForPaths.add(path);
                 }
             } else {
@@ -720,11 +722,11 @@ public class LazyGeneratedCodecRegistry implements //
             }
         }
 
-        abstract protected T tryToLoadImplementation(Class<? extends DataContainer> inputType);
+        protected abstract T tryToLoadImplementation(Class<? extends DataContainer> inputType);
 
-        abstract protected void tryToLoadImplementations();
+        protected abstract void tryToLoadImplementations();
 
-        abstract protected void adaptForPathImpl(InstanceIdentifier<?> path, DataNodeContainer ctx);
+        protected abstract void adaptForPathImpl(InstanceIdentifier<?> path, DataNodeContainer ctx);
     }
 
     @SuppressWarnings("rawtypes")
@@ -968,7 +970,7 @@ public class LazyGeneratedCodecRegistry implements //
      *            Key type
      */
     @SuppressWarnings("rawtypes")
-    private static abstract class MapFacadeBase<T> implements Map<T, BindingCodec<?, ?>> {
+    private abstract static class MapFacadeBase<T> implements Map<T, BindingCodec<?, ?>> {
 
         @Override
         public boolean containsKey(final Object key) {
@@ -1377,7 +1379,10 @@ public class LazyGeneratedCodecRegistry implements //
 
     }
 
-    public boolean isCodecAvailable(final Class<? extends DataContainer> cls) {
+    public boolean isCodecAvailable(final Class<?> cls) {
+        // FIXME: enforce type?
+        // Preconditions.checkArgument(DataContainer.class.isAssignableFrom(cls));
+
         if (containerCodecs.containsKey(cls)) {
             return true;
         }