import java.util.AbstractMap.SimpleEntry
import org.opendaylight.yangtools.yang.model.api.SchemaPath
import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
-import java.util.ArrayList
-import org.opendaylight.yangtools.yang.common.QName
import org.opendaylight.yangtools.yang.binding.DataContainer
-import static com.google.common.base.Preconditions.*;
-import java.util.List
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import org.opendaylight.yangtools.concepts.Delegator
import java.util.concurrent.ConcurrentMap
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import org.opendaylight.yangtools.yang.binding.BindingCodec
import com.google.common.collect.HashMultimap
import com.google.common.util.concurrent.SettableFuture
import java.util.concurrent.Future
import org.opendaylight.controller.sal.binding.dom.serializer.api.ValueWithQName
import org.opendaylight.controller.sal.binding.dom.serializer.api.DataContainerCodec
import org.opendaylight.yangtools.binding.generator.util.Types
+import org.osgi.framework.BundleContext
+import java.util.Hashtable
+import org.osgi.framework.ServiceRegistration
+import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException
+import java.util.concurrent.Callable
+import org.opendaylight.yangtools.yang.binding.Augmentation
+import org.opendaylight.controller.sal.binding.impl.util.YangSchemaUtils
-class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener {
+class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable {
@Property
ClassPool pool;
val promisedSchemas = HashMultimap.<Type, SettableFuture<SchemaNode>>create;
+ ServiceRegistration<SchemaServiceListener> listenerRegistration
+
override onGlobalContextUpdated(SchemaContext arg0) {
recreateBindingContext(arg0);
registry.onGlobalContextUpdated(arg0);
for (entry : newBinding.moduleContexts.entrySet) {
registry.onModuleContextAdded(schemaContext, entry.key, entry.value);
-
+ binding.pathToType.putAll(entry.value.childNodes)
//val module = entry.key;
val context = entry.value;
updateBindingFor(context.childNodes, schemaContext);
updateBindingFor(context.cases, schemaContext);
-
val typedefs = context.typedefs;
- for (typedef : typedefs.values) {
- binding.typeDefinitions.put(typedef, typedef as GeneratedType);
+ for (typedef : typedefs.entrySet) {
+ val typeRef = new ReferencedTypeImpl(typedef.value.packageName,typedef.value.name)
+ binding.typeDefinitions.put(typeRef, typedef.value as GeneratedType);
+ val schemaNode = YangSchemaUtils.findTypeDefinition(schemaContext,typedef.key);
+ if(schemaNode != null) {
+
+ binding.typeToSchemaNode.put(typeRef,schemaNode);
+ } else {
+ LOG.error("Type definition for {} is not available",typedef.value);
+ }
+
}
val augmentations = context.augmentations;
for (augmentation : augmentations) {
binding.typeToDefinition.put(augmentation, augmentation);
}
-
+
binding.typeToAugmentation.putAll(context.typeToAugmentation);
}
}
return ret as CompositeNode;
}
- private def waitForSchema(Class<? extends DataContainer> class1) {
+ private def void waitForSchema(Class<? extends DataContainer> class1) {
+ if(Augmentation.isAssignableFrom(class1)) {
+ /* FIXME: We should wait also for augmentations. Currently YANGTools does not provide correct
+ * mapping between java Augmentation classes and augmentations.
+ */
+ return;
+ }
+
val ref = Types.typeForClass(class1);
getSchemaWithRetry(ref);
}
}
override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode node) {
- if (node == null) {
- return null;
+ return tryDeserialization[ |
+ if (node == null) {
+ return null;
+ }
+ val targetType = path.targetType
+ val transformer = registry.getCodecForDataObject(targetType);
+ val ret = transformer.deserialize(node)?.value as DataObject;
+ return ret;
+ ]
+ }
+
+ override fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) {
+ return tryDeserialization[ |
+ registry.instanceIdentifierCodec.deserialize(entry);
+ ]
+ }
+
+ private static def <T> T tryDeserialization(Callable<T> deserializationBlock) throws DeserializationException {
+ try {
+ deserializationBlock.call()
+ } catch (Exception e) {
+
+ // FIXME: Make this block providing more information.
+ throw new DeserializationException(e);
}
- val targetType = path.targetType
- val transformer = registry.getCodecForDataObject(targetType);
- val ret = transformer.deserialize(node)?.value as DataObject;
- return ret;
}
private def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
+
for (entry : map.entrySet) {
val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
+
//LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName)
+ val typeRef = new ReferencedTypeImpl(entry.value.packageName,entry.value.name)
+ typeToDefinition.put(typeRef, entry.value);
if (schemaNode != null) {
- typeToSchemaNode.put(entry.value, schemaNode);
- typeToDefinition.put(entry.value, entry.value);
- updatePromisedSchemas(entry.value, schemaNode);
+ typeToSchemaNode.put(typeRef, schemaNode);
+ updatePromisedSchemas(typeRef, schemaNode);
}
+
}
}
- public def void start() {
+ public def void start(BundleContext ctx) {
binding = new TransformerGenerator(pool);
registry = new LazyGeneratedCodecRegistry()
registry.generator = binding
binding.typeToDefinition = typeToDefinition
binding.typeToSchemaNode = typeToSchemaNode
binding.typeDefinitions = typeDefinitions
-
+ if (ctx !== null) {
+ listenerRegistration = ctx.registerService(SchemaServiceListener, this, new Hashtable<String, String>());
+ }
}
private def getTypeDefinition(Type type) {
if (typeDef !== null) {
return typeDef;
}
+ LOG.info("Thread blocked waiting for schema for: {}",type.fullyQualifiedName)
return type.getSchemaInFuture.get();
}
}
promisedSchemas.removeAll(builder);
}
+
+ override close() throws Exception {
+ listenerRegistration?.unregister();
+ }
+
}