BUG-1611: make sure runtime components create short comments
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / RuntimeGeneratedMappingServiceImpl.java
index 8ac4a9441a9fbb43f0171b7deb6917ea1a0c34ac..29a532228dd54bfc6421c34035af5f91f923cafb 100644 (file)
@@ -7,6 +7,14 @@
  */
 package org.opendaylight.yangtools.sal.binding.generator.impl;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+import java.net.URI;
 import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -41,10 +49,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
 import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
 import org.opendaylight.yangtools.yang.data.impl.codec.AugmentationCodec;
@@ -67,14 +75,8 @@ import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.util.concurrent.SettableFuture;
-
 public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaContextListener,
-        SchemaLock, AutoCloseable, SchemaContextHolder, TypeResolver {
+SchemaLock, AutoCloseable, SchemaContextHolder, TypeResolver {
 
     private static final Logger LOG = LoggerFactory.getLogger(RuntimeGeneratedMappingServiceImpl.class);
 
@@ -88,10 +90,9 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
 
     private final ClassLoadingStrategy classLoadingStrategy;
 
-    // FIXME: will become final
-    private ClassPool pool;
-    private AbstractTransformerGenerator binding;
-    private LazyGeneratedCodecRegistry registry;
+    private final AbstractTransformerGenerator binding;
+    private final LazyGeneratedCodecRegistry registry;
+    private final ClassPool pool;
 
     /*
      * FIXME: updated here, access from AbstractTransformer
@@ -105,16 +106,6 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
     private final ConcurrentMap<Type, Type> typeDefinitions = new ConcurrentHashMap<>();
     private SchemaContext schemaContext;
 
-    @Deprecated
-    public RuntimeGeneratedMappingServiceImpl() {
-        this(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
-    }
-
-    @Deprecated
-    public RuntimeGeneratedMappingServiceImpl(final ClassLoadingStrategy strat) {
-        classLoadingStrategy = strat;
-    }
-
     public RuntimeGeneratedMappingServiceImpl(final ClassPool pool) {
         this(pool, GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
     }
@@ -122,27 +113,17 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
     public RuntimeGeneratedMappingServiceImpl(final ClassPool pool, final ClassLoadingStrategy strat) {
         this.pool = Preconditions.checkNotNull(pool);
         this.classLoadingStrategy = Preconditions.checkNotNull(strat);
-
-        // FIXME: merge into constructor once legacy init() is removed
-        doInit();
-    }
-
-    private void doInit() {
+        // FIXME: this escapes constructor
         binding = new TransformerGenerator(this, pool);
         registry = new LazyGeneratedCodecRegistry(this, binding, classLoadingStrategy);
         binding.setListener(registry);
 
         // if (ctx !== null) {
-        // listenerRegistration = ctx.registerService(SchemaServiceListener,
+        // listenerRegistration = ctx.registerService(SchemaContextListener,
         // this, new Hashtable<String, String>());
         // }
     }
 
-    @Deprecated
-    public void setPool(final ClassPool pool) {
-        this.pool = pool;
-    }
-
     @Override
     public synchronized SchemaContext getSchemaContext() {
         return schemaContext;
@@ -157,7 +138,7 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
 
     @GuardedBy("this")
     private void recreateBindingContext(final SchemaContext schemaContext) {
-        BindingGeneratorImpl newBinding = new BindingGeneratorImpl();
+        BindingGeneratorImpl newBinding = new BindingGeneratorImpl(false);
         newBinding.generateTypes(schemaContext);
 
         for (Map.Entry<Module, ModuleContext> entry : newBinding.getModuleContexts().entrySet()) {
@@ -210,17 +191,17 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
     }
 
     @Override
-    public Entry<InstanceIdentifier, CompositeNode> toDataDom(
+    public Entry<YangInstanceIdentifier, CompositeNode> toDataDom(
             final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
         try {
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier key = toDataDom(entry.getKey());
+            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier key = toDataDom(entry.getKey());
             CompositeNode data;
             if (Augmentation.class.isAssignableFrom(entry.getKey().getTargetType())) {
                 data = toCompositeNodeImplAugument(key, entry.getValue());
             } else {
                 data = toCompositeNodeImpl(key, entry.getValue());
             }
-            return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>(key,
+            return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode>(key,
                     data);
 
         } catch (Exception e) {
@@ -236,9 +217,9 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
         return codec.serialize(new ValueWithQName<DataObject>(null, object));
     }
 
-    private CompositeNode toCompositeNodeImpl(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier,
+    private CompositeNode toCompositeNodeImpl(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier identifier,
             final DataObject object) {
-        PathArgument last = identifier.getPath().get(identifier.getPath().size() - 1);
+        PathArgument last = identifier.getLastPathArgument();
         Class<? extends DataContainer> cls = object.getImplementedInterface();
         waitForSchema(cls);
         DataContainerCodec<DataObject> codec = (DataContainerCodec<DataObject>) registry.getCodecForDataObject(cls);
@@ -246,12 +227,11 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
     }
 
     private CompositeNode toCompositeNodeImplAugument(
-            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier, final DataObject object) {
+            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier identifier, final DataObject object) {
 
         // val cls = object.implementedInterface;
         // waitForSchema(cls);
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument last = identifier.getPath().get(
-                identifier.getPath().size() - 1);
+        org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument last = identifier.getLastPathArgument();
         AugmentationCodec codec = registry.getCodecForAugmentation((Class) object.getImplementedInterface());
         CompositeNode ret = codec.serialize(new ValueWithQName<DataObject>(last.getNodeType(), object));
         if (last instanceof NodeIdentifierWithPredicates) {
@@ -260,7 +240,7 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
             for (Map.Entry<QName, Object> predicate : predicates.getKeyValues().entrySet()) {
                 newNodes.add(new SimpleNodeTOImpl<Object>(predicate.getKey(), null, predicate.getValue()));
             }
-            newNodes.addAll(ret.getChildren());
+            newNodes.addAll(ret.getValue());
             return new CompositeNodeTOImpl(last.getNodeType(), null, newNodes);
         }
         return ret;
@@ -268,19 +248,20 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
 
     @Override
     public void waitForSchema(final Class<?> cls) {
-        if (!registry.isCodecAvailable(cls)) {
-            final Type ref = Types.typeForClass(cls);
+        final ListenableFuture<Type> f = getSchemaDefinition(cls);
+        if (f != null) {
             try {
-                getSchemaWithRetry(ref);
+                f.get();
             } catch (InterruptedException | ExecutionException e) {
                 LOG.warn("Waiting for schema for class {} failed", cls, e);
                 throw new IllegalStateException(String.format("Failed to get schema for %s", cls), e);
             }
+            LOG.info("Schema for {} became available, thread unblocked", cls);
         }
     }
 
     @Override
-    public InstanceIdentifier toDataDom(
+    public YangInstanceIdentifier toDataDom(
             final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
         for (final org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : path.getPathArguments()) {
             this.waitForSchema(arg.getType());
@@ -320,7 +301,7 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
     }
 
     @Override
-    public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object> fromDataDom(final InstanceIdentifier entry) throws DeserializationException {
+    public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object> fromDataDom(final YangInstanceIdentifier entry) throws DeserializationException {
         try {
             final InstanceIdentifierCodec c = registry.getInstanceIdentifierCodec();
             Preconditions.checkState(c != null, "InstanceIdentifierCodec not present");
@@ -350,10 +331,6 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
         }
     }
 
-    @Deprecated
-    public void init() {
-        doInit();
-    }
 
     @Override
     public Set<QName> getRpcQNamesFor(final Class<? extends RpcService> service) {
@@ -365,21 +342,18 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
         return serviceRef;
     }
 
-    private void getSchemaWithRetry(final Type type) throws InterruptedException, ExecutionException {
-        final SettableFuture<Type> f;
-
+    private ListenableFuture<Type> getSchemaDefinition(final Class<?> cls) {
+        final Type type = Types.typeForClass(cls);
         synchronized (this) {
             if (typeToDefinition.containsKey(type)) {
-                return;
+                return null;
             }
 
-            LOG.info("Thread blocked waiting for schema for: {}", type.getFullyQualifiedName());
-            f = SettableFuture.create();
+            LOG.info("Thread is going to wait for schema for: {}", type.getFullyQualifiedName());
+            final SettableFuture<Type> f = SettableFuture.create();
             promisedTypes.put(type, f);
+            return f;
         }
-
-        f.get();
-        LOG.info("Schema for {} became available, thread unblocked", type.getFullyQualifiedName());
     }
 
     @GuardedBy("this")
@@ -422,7 +396,7 @@ public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMap
     public synchronized Optional<Class<? extends RpcService>> getRpcServiceClassFor(final String namespace, final String revision) {
         Module module = null;
         if (schemaContext != null) {
-            module = schemaContext.findModuleByName(namespace, QName.parseRevision(revision));
+            module = schemaContext.findModuleByNamespaceAndRevision(URI.create(namespace), QName.parseRevision(revision));
         }
         if (module == null) {
             return Optional.absent();