private static final Map<List<QName>, Type> pathToInstantiatedType = new ConcurrentHashMap<>();
private static final Map<Type, QName> typeToQname = new ConcurrentHashMap<>();
+ private final SchemaLock lock;
+
private SchemaContext currentSchema;
+ LazyGeneratedCodecRegistry(SchemaLock lock) {
+ this.lock = Preconditions.checkNotNull(lock);
+ }
+
+ public SchemaLock getLock() {
+ return lock;
+ }
+
public TransformerGenerator getGenerator() {
return generator;
}
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();
import org.opendaylight.yangtools.yang.common.QName
import com.google.common.collect.FluentIterable
import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
+import java.util.HashMap
-class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable {
+class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, SchemaLock, AutoCloseable {
@Property
ClassPool pool;
val promisedTypeDefinitions = HashMultimap.<Type, SettableFuture<GeneratedTypeBuilder>>create;
- val promisedSchemas = HashMultimap.<Type, SettableFuture<SchemaNode>>create;
+ val promisedTypes = HashMultimap.<Type, SettableFuture<Type>>create;
//ServiceRegistration<SchemaServiceListener> listenerRegistration
for (augmentation : augmentations) {
binding.typeToDefinition.put(augmentation, augmentation);
}
-
binding.typeToAugmentation.putAll(context.typeToAugmentation);
+ for(augmentation : augmentations) {
+ updatePromisedSchemas(augmentation);
+ }
}
}
return ret as CompositeNode;
}
- 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;
- }
+ override waitForSchema(Class class1) {
+
if(registry.isCodecAvailable(class1)) {
return;
}
typeToDefinition.put(typeRef, entry.value);
if (schemaNode != null) {
typeToSchemaNode.put(typeRef, schemaNode);
- updatePromisedSchemas(typeRef, schemaNode);
+ updatePromisedSchemas(entry.value);
}
}
public def void init() {
binding = new TransformerGenerator(pool);
- registry = new LazyGeneratedCodecRegistry()
+ registry = new LazyGeneratedCodecRegistry(this)
registry.generator = binding
//binding.staticFieldsInitializer = registry
return serviceTypeToRpc.get(new ReferencedTypeImpl(service.package.name,service.simpleName));
}
- private def getSchemaWithRetry(Type type) {
- val typeDef = typeToSchemaNode.get(type);
- if (typeDef !== null) {
- return typeDef;
+ private def void getSchemaWithRetry(Type type) {
+ if (typeToDefinition.containsKey(type)) {
+ return;
}
LOG.trace("Thread blocked waiting for schema for: {}",type.fullyQualifiedName)
- return type.getSchemaInFuture.get();
+ type.waitForTypeDefinition.get();
}
- private def Future<SchemaNode> getSchemaInFuture(Type type) {
- val future = SettableFuture.<SchemaNode>create()
- promisedSchemas.put(type, future);
+ private def Future<Type> waitForTypeDefinition(Type type) {
+ val future = SettableFuture.<Type>create()
+ promisedTypes.put(type, future);
return future;
}
- private def void updatePromisedSchemas(Type builder, SchemaNode schema) {
+ private def void updatePromisedSchemas(Type builder) {
val ref = new ReferencedTypeImpl(builder.packageName, builder.name);
- val futures = promisedSchemas.get(ref);
+ val futures = promisedTypes.get(ref);
if (futures === null || futures.empty) {
return;
}
for (future : futures) {
- future.set(schema);
+ future.set(builder);
}
- promisedSchemas.removeAll(builder);
+ promisedTypes.removeAll(builder);
}
override close() throws Exception {