X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fdom%2Fserializer%2Fimpl%2FLazyGeneratedCodecRegistry.java;h=d33272d6413bfa90628f49a459671eab756ef2d0;hb=43f506ead639607367b6bdc8a04287b57e189b01;hp=e8e4c4375dba6548d7aa58fb81820c616d920f66;hpb=90e562e3dcc64e46a657ef4ab3047b2b709339c7;p=controller.git diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java index e8e4c4375d..d33272d641 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/LazyGeneratedCodecRegistry.java @@ -2,7 +2,6 @@ package org.opendaylight.controller.sal.binding.dom.serializer.impl; import java.lang.ref.WeakReference; import java.lang.reflect.Field; -import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -27,6 +26,7 @@ import org.opendaylight.controller.sal.binding.dom.serializer.api.DomCodec; import org.opendaylight.controller.sal.binding.dom.serializer.api.IdentifierCodec; import org.opendaylight.controller.sal.binding.dom.serializer.api.InstanceIdentifierCodec; import org.opendaylight.controller.sal.binding.dom.serializer.api.ValueWithQName; +import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils; import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener; import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl; import org.opendaylight.yangtools.binding.generator.util.Types; @@ -36,10 +36,13 @@ import org.opendaylight.yangtools.yang.binding.Augmentable; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.BindingCodec; import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ChoiceNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -48,6 +51,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.UsesNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,6 +65,8 @@ import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTy import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import com.google.common.util.concurrent.CycleDetectingLockFactory.WithExplicitOrdering; + public class LazyGeneratedCodecRegistry implements // CodecRegistry, // SchemaServiceListener, // @@ -85,11 +91,12 @@ public class LazyGeneratedCodecRegistry implements // Map> typeToClass = new ConcurrentHashMap<>(); @SuppressWarnings("rawtypes") - private ConcurrentMap typeToCaseNodes = new ConcurrentHashMap<>(); + private ConcurrentMap typeToCaseCodecs = new ConcurrentHashMap<>(); private CaseClassMapFacade classToCaseRawCodec = new CaseClassMapFacade(); Map pathToType = new ConcurrentHashMap<>(); + Map, Type> pathToInstantiatedType = new ConcurrentHashMap<>(); private SchemaContext currentSchema; @@ -116,13 +123,27 @@ public class LazyGeneratedCodecRegistry implements // public Class getClassForPath(List names) { DataSchemaNode node = getSchemaNode(names); SchemaPath path = node.getPath(); - GeneratedTypeBuilder type = pathToType.get(path); - ReferencedTypeImpl typeref = new ReferencedTypeImpl(type.getPackageName(), type.getName()); + Type type = pathToType.get(path); + if (type != null) { + type = new ReferencedTypeImpl(type.getPackageName(), type.getName()); + } else { + type = pathToInstantiatedType.get(names); + } @SuppressWarnings("rawtypes") - WeakReference weakRef = typeToClass.get(typeref); + WeakReference weakRef = typeToClass.get(type); + if (weakRef == null) { + LOG.error("Could not find loaded class for path: {} and type: {}", path, type.getFullyQualifiedName()); + } return weakRef.get(); } + @Override + public void putPathToClass(List names, Class cls) { + Type reference = Types.typeForClass(cls); + pathToInstantiatedType.put(names, reference); + bindingClassEncountered(cls); + } + @Override public IdentifierCodec getKeyCodecForPath(List names) { @SuppressWarnings("unchecked") @@ -147,9 +168,31 @@ public class LazyGeneratedCodecRegistry implements // @Override @SuppressWarnings("rawtypes") public void bindingClassEncountered(Class cls) { + ConcreteType typeRef = Types.typeForClass(cls); + if (typeToClass.containsKey(typeRef)) { + return; + } + LOG.info("Binding Class {} encountered.", cls); WeakReference weakRef = new WeakReference<>(cls); typeToClass.put(typeRef, weakRef); + if (Augmentation.class.isAssignableFrom(cls)) { + + } else if (DataObject.class.isAssignableFrom(cls)) { + @SuppressWarnings({ "unchecked", "unused" }) + Object cdc = getCodecForDataObject((Class) cls); + } + } + + @Override + public void onClassProcessed(Class cls) { + ConcreteType typeRef = Types.typeForClass(cls); + if (typeToClass.containsKey(typeRef)) { + return; + } + LOG.info("Binding Class {} encountered.", cls); + WeakReference weakRef = new WeakReference<>((Class) cls); + typeToClass.put(typeRef, weakRef); } private DataSchemaNode getSchemaNode(List path) { @@ -253,10 +296,12 @@ public class LazyGeneratedCodecRegistry implements // return potential; } ConcreteType typeref = Types.typeForClass(caseClass); - ChoiceCaseCodecImpl caseCodec = typeToCaseNodes.get(typeref); + ChoiceCaseCodecImpl caseCodec = typeToCaseCodecs.get(typeref); + checkState(caseCodec != null, "Case Codec was not created proactivelly for %s", caseClass.getName()); + checkState(caseCodec.getSchema() != null, "Case schema is not available for %s", caseClass.getName()); @SuppressWarnings("unchecked") - Class newCodec = generator.caseCodecFor(caseClass, caseCodec.schema); + Class newCodec = generator.caseCodecFor(caseClass, caseCodec.getSchema()); BindingCodec newInstance = newInstanceOf(newCodec); caseCodec.setDelegate(newInstance); caseCodecs.put(caseClass, caseCodec); @@ -271,7 +316,6 @@ public class LazyGeneratedCodecRegistry implements // public void onModuleContextAdded(SchemaContext schemaContext, Module module, ModuleContext context) { pathToType.putAll(context.getChildNodes()); - captureCases(context.getCases(), schemaContext); } @@ -279,10 +323,23 @@ public class LazyGeneratedCodecRegistry implements // for (Entry caseNode : cases.entrySet()) { ReferencedTypeImpl typeref = new ReferencedTypeImpl(caseNode.getValue().getPackageName(), caseNode .getValue().getName()); + + LOG.info("Case path: {} Type : {}", caseNode.getKey(), caseNode.getValue().getFullyQualifiedName()); + pathToType.put(caseNode.getKey(), caseNode.getValue()); + ChoiceCaseNode node = (ChoiceCaseNode) SchemaContextUtil.findDataSchemaNode(module, caseNode.getKey()); + + if (node == null) { + LOG.error("YANGTools Bug: SchemaNode for {}, with path {} was not found in context.", + typeref.getFullyQualifiedName(), caseNode.getKey()); + @SuppressWarnings("rawtypes") + ChoiceCaseCodecImpl value = new ChoiceCaseCodecImpl(); + typeToCaseCodecs.putIfAbsent(typeref, value); + continue; + } @SuppressWarnings("rawtypes") ChoiceCaseCodecImpl value = new ChoiceCaseCodecImpl(node); - typeToCaseNodes.putIfAbsent(typeref, value); + typeToCaseCodecs.putIfAbsent(typeref, value); } } @@ -294,33 +351,50 @@ public class LazyGeneratedCodecRegistry implements // @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public void onChoiceCodecCreated(Class choiceClass, - Class, Object>> choiceCodec) { + Class, Object>> choiceCodec, ChoiceNode schema) { ChoiceCodec oldCodec = choiceCodecs.get(choiceClass); checkState(oldCodec == null); BindingCodec, Object> delegate = newInstanceOf(choiceCodec); ChoiceCodecImpl newCodec = new ChoiceCodecImpl(delegate); choiceCodecs.put(choiceClass, newCodec); - CodecMapping.setClassToCaseMap(choiceCodec, (Map) classToCaseRawCodec); + CodecMapping.setClassToCaseMap(choiceCodec, (Map, BindingCodec>) classToCaseRawCodec); CodecMapping.setCompositeNodeToCaseMap(choiceCodec, newCodec.getCompositeToCase()); + tryToCreateCasesCodecs(schema); + + } + + private void tryToCreateCasesCodecs(ChoiceNode schema) { + for (ChoiceCaseNode caseNode : schema.getCases()) { + SchemaPath path = caseNode.getPath(); + GeneratedTypeBuilder type; + if (path != null && (type = pathToType.get(path)) != null) { + ReferencedTypeImpl typeref = new ReferencedTypeImpl(type.getPackageName(), type.getName()); + ChoiceCaseCodecImpl partialCodec = typeToCaseCodecs.get(typeref); + if(partialCodec.getSchema() == null ) { + partialCodec.setSchema(caseNode); + } + + Class caseClass = ClassLoaderUtils.tryToLoadClassWithTCCL(type.getFullyQualifiedName()); + if (caseClass != null) { + getCaseCodecFor(caseClass); + } + } + } + } @Override public void onValueCodecCreated(Class valueClass, Class valueCodec) { - // TODO Auto-generated method stub - } @Override public void onCaseCodecCreated(Class choiceClass, Class, Object>> choiceCodec) { - // TODO Auto-generated method stub - } @Override - public void onDataContainerCodecCreated(Class dataClass, - Class, Object>> dataCodec) { + public void onDataContainerCodecCreated(Class dataClass, Class> dataCodec) { if (Augmentable.class.isAssignableFrom(dataClass)) { AugmentableCompositeCodec augmentableCodec = getAugmentableCodec(dataClass); CodecMapping.setAugmentationCodec(dataCodec, augmentableCodec); @@ -409,15 +483,15 @@ public class LazyGeneratedCodecRegistry implements // @SuppressWarnings("rawtypes") private static class ChoiceCaseCodecImpl implements ChoiceCaseCodec, // Delegator { - private final boolean augmenting; + private boolean augmenting; private BindingCodec delegate; - private final Set validNames; - private final Set validQNames; + private Set validNames; + private Set validQNames; private ChoiceCaseNode schema; - public ChoiceCaseCodecImpl(ChoiceCaseNode caseNode) { - this.delegate = NOT_READY_CODEC; + public void setSchema(ChoiceCaseNode caseNode) { + this.schema = schema; this.schema = caseNode; validNames = new HashSet<>(); validQNames = new HashSet<>(); @@ -429,6 +503,15 @@ public class LazyGeneratedCodecRegistry implements // augmenting = caseNode.isAugmenting(); } + public ChoiceCaseCodecImpl() { + this.delegate = NOT_READY_CODEC; + } + + public ChoiceCaseCodecImpl(ChoiceCaseNode caseNode) { + this.delegate = NOT_READY_CODEC; + setSchema(caseNode); + } + @Override public ValueWithQName deserialize(Node input) { throw new UnsupportedOperationException("Direct invocation of this codec is not allowed."); @@ -453,7 +536,7 @@ public class LazyGeneratedCodecRegistry implements // @Override public boolean isAcceptable(Node input) { - if (false == (input instanceof CompositeNode)) { + if (input instanceof CompositeNode) { if (augmenting) { return checkAugmenting((CompositeNode) input); } else { @@ -467,10 +550,8 @@ public class LazyGeneratedCodecRegistry implements // QName parent = input.getNodeType(); for (Node childNode : input.getChildren()) { QName child = childNode.getNodeType(); - if (false == Objects.equals(parent.getNamespace(), child.getNamespace())) { - continue; - } - if (false == Objects.equals(parent.getRevision(), child.getRevision())) { + if (!Objects.equals(parent.getNamespace(), child.getNamespace()) + || !Objects.equals(parent.getRevision(), child.getRevision())) { continue; } if (validNames.contains(child.getLocalName())) { @@ -533,14 +614,14 @@ public class LazyGeneratedCodecRegistry implements // @Override public Set>> entrySet() { - return null; + return Collections.emptySet(); } @Override public BindingCodec get(Object key) { if (key instanceof Class) { Class cls = (Class) key; - bindingClassEncountered(cls); + // bindingClassEncountered(cls); ChoiceCaseCodecImpl caseCodec = getCaseCodecFor(cls); return caseCodec.getDelegate(); } @@ -557,14 +638,9 @@ public class LazyGeneratedCodecRegistry implements // this.choiceCases = choiceCases; } - @Override - public Set> entrySet() { - return null; - } - @Override public BindingCodec get(Object key) { - if (false == (key instanceof CompositeNode)) { + if (!(key instanceof CompositeNode)) { return null; } for (java.util.Map.Entry> entry : choiceCases.entrySet()) { @@ -575,6 +651,7 @@ public class LazyGeneratedCodecRegistry implements // } return null; } + } /** @@ -585,7 +662,7 @@ public class LazyGeneratedCodecRegistry implements // * Key type */ @SuppressWarnings("rawtypes") - private static abstract class MapFacadeBase implements Map { + private static abstract class MapFacadeBase implements Map> { @Override public boolean containsKey(Object key) { @@ -613,8 +690,8 @@ public class LazyGeneratedCodecRegistry implements // } @Override - public Collection values() { - return null; + public Collection> values() { + return Collections.emptySet(); } private UnsupportedOperationException notModifiable() { @@ -622,12 +699,12 @@ public class LazyGeneratedCodecRegistry implements // } @Override - public BindingCodec, Object> put(T key, BindingCodec value) { + public BindingCodec, Object> put(T key, BindingCodec value) { throw notModifiable(); } @Override - public void putAll(Map m) { + public void putAll(Map> m) { throw notModifiable(); } @@ -638,17 +715,17 @@ public class LazyGeneratedCodecRegistry implements // @Override public boolean isEmpty() { - return false; + return true; } @Override public Set keySet() { - return null; + return Collections.emptySet(); } @Override - public Set> entrySet() { - return null; + public Set>> entrySet() { + return Collections.emptySet(); } @Override @@ -686,14 +763,8 @@ public class LazyGeneratedCodecRegistry implements // augmentationField.setAccessible(true); Map augMap = (Map) augmentationField.get(input); return augMap; - } catch (NoSuchFieldException e) { - - } catch (SecurityException e) { - - } catch (IllegalArgumentException e) { - - } catch (IllegalAccessException e) { - + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) { + LOG.debug("Could not read augmentations for {}", input, e); } return Collections.emptyMap(); } @@ -719,9 +790,9 @@ public class LazyGeneratedCodecRegistry implements // rawAugmentationCodecs.put(key, ret); return ret; } catch (InstantiationException e) { - + LOG.error("Can not instantiate raw augmentation codec {}", key.getSimpleName(), e); } catch (IllegalAccessException e) { - + LOG.debug("BUG: Constructor for {} is not accessible.", key.getSimpleName(), e); } return null; }