+ protected void adaptForPathImpl(final InstanceIdentifier<?> augTarget, final DataNodeContainer ctxNode) {
+ if (ctxNode instanceof AugmentationTarget) {
+ Set<AugmentationSchema> availableAugmentations = ((AugmentationTarget) ctxNode)
+ .getAvailableAugmentations();
+ if (!availableAugmentations.isEmpty()) {
+ updateAugmentationMapping(augTarget, availableAugmentations);
+ }
+ }
+ }
+
+ /**
+ *
+ * Adapts augmentation codec for specific provider location (target)
+ *
+ * Since augmentation are not forward-referencing and may be discovered
+ * during runtime, we need to adapt {@link AugmentableDispatchCodec},
+ * {@link AugmentationCodecWrapper} and {@link InstanceIdentifierCodec}
+ * for this newly discovered location where augmentation may be used.
+ *
+ * Adaptation consists of:
+ * <ol>
+ * <li>scan of available (valid) augmentations for current location
+ * <li>lookup for Java classes derived from this augmentations
+ * <li>generation of missing codecs
+ * <li>updating Augmentation codecs to work with new location
+ * <li>updating Instance Identifier to work with new location
+ *
+ */
+ private void updateAugmentationMapping(final InstanceIdentifier<?> augTarget,
+ final Set<AugmentationSchema> availableAugmentations) {
+ for (AugmentationSchema aug : availableAugmentations) {
+
+ Type potentialType = getTypeForAugmentation(aug);
+ if (potentialType != null) {
+ Optional<AugmentationCodecWrapper> potentialImpl = tryToLoadImplementation(potentialType);
+ if (potentialImpl.isPresent()) {
+ potentialImpl.get().addApplicableFor(augTarget, aug);
+ Class augType = potentialImpl.get().getDataType();
+ InstanceIdentifier augPath = augTarget.augmentation(augType);
+ try {
+
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = getRegistry().getInstanceIdentifierCodec()
+ .serialize(augPath);
+ if (domPath == null) {
+ LOG.error("Unable to serialize instance identifier for {}", augPath);
+ }
+ } catch (Exception e) {
+ LOG.error("Unable to serialize instance identifiers for {}", augPath, e);
+ }
+
+ }
+ } else {
+ // Omits warning for empty augmentations since they are not
+ // represented in data
+ if (!aug.getChildNodes().isEmpty()) {
+ LOG.warn("Could not find generated type for augmentation {} with children {}", aug,
+ aug.getChildNodes());
+ }
+ }
+ }
+ }
+
+ private Type getTypeForAugmentation(final AugmentationSchema aug) {
+ Optional<AugmentationSchema> currentAug = Optional.of(aug);
+ while (currentAug.isPresent()) {
+ Type potentialType = typeToAugment.inverse().get(currentAug.get());
+ if (potentialType != null) {
+ return potentialType;
+ }
+ currentAug = currentAug.get().getOriginalDefinition();
+ }
+ return null;