From eb237bebc987f10e24ddd4fea8e7f5359e201639 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 6 Apr 2020 14:23:06 +0200 Subject: [PATCH] Migrate away from sal-common-impl DataNormalizer and related classes are deprecated for removal, and are used only by are deprecated RESTCONF implementation. Rehost the three required classes as a private detail. Change-Id: Id5539948881d503fbe5e223c41cfa7a9a2284109 Signed-off-by: Robert Varga --- restconf/restconf-nb-bierman02/pom.xml | 4 - .../sal/restconf/impl/ControllerContext.java | 3 - .../impl/DataNormalizationException.java | 20 + .../impl/DataNormalizationOperation.java | 605 ++++++++++++++++++ .../sal/restconf/impl/DataNormalizer.java | 76 +++ 5 files changed, 701 insertions(+), 7 deletions(-) create mode 100644 restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationException.java create mode 100644 restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationOperation.java create mode 100644 restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizer.java diff --git a/restconf/restconf-nb-bierman02/pom.xml b/restconf/restconf-nb-bierman02/pom.xml index 9a8374cfca..dc61c21f56 100644 --- a/restconf/restconf-nb-bierman02/pom.xml +++ b/restconf/restconf-nb-bierman02/pom.xml @@ -69,10 +69,6 @@ org.opendaylight.controller sal-common-util - - org.opendaylight.controller - sal-common-impl - org.opendaylight.yangtools yang-data-api diff --git a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java index a2d2eb80cc..648205dc19 100644 --- a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java +++ b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java @@ -36,9 +36,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import javax.ws.rs.core.Response.Status; import org.apache.aries.blueprint.annotation.service.Reference; -import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException; -import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation; -import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer; import org.opendaylight.mdsal.dom.api.DOMMountPoint; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.mdsal.dom.api.DOMSchemaService; diff --git a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationException.java b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationException.java new file mode 100644 index 0000000000..9bee9db12c --- /dev/null +++ b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationException.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.sal.restconf.impl; + +final class DataNormalizationException extends Exception { + private static final long serialVersionUID = 1L; + + DataNormalizationException(final String message) { + super(message); + } + + DataNormalizationException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationOperation.java b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationOperation.java new file mode 100644 index 0000000000..327a7bb906 --- /dev/null +++ b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizationOperation.java @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.sal.restconf.impl; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import org.eclipse.jdt.annotation.Nullable; +import org.gaul.modernizer_maven_annotations.SuppressModernizer; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; +import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; +import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema; + +abstract class DataNormalizationOperation implements Identifiable { + private final T identifier; + private final DataSchemaNode dataSchemaNode; + + @Override + public T getIdentifier() { + return identifier; + } + + protected DataNormalizationOperation(final T identifier, final SchemaNode schema) { + this.identifier = identifier; + dataSchemaNode = schema instanceof DataSchemaNode ? (DataSchemaNode)schema : null; + } + + public boolean isMixin() { + return false; + } + + + public boolean isKeyedEntry() { + return false; + } + + protected Set getQNameIdentifiers() { + return Collections.singleton(identifier.getNodeType()); + } + + public abstract DataNormalizationOperation getChild(PathArgument child) throws DataNormalizationException; + + public abstract DataNormalizationOperation getChild(QName child) throws DataNormalizationException; + + public abstract boolean isLeaf(); + + @SuppressModernizer + public Optional getDataSchemaNode() { + return Optional.fromNullable(dataSchemaNode); + } + + private abstract static class SimpleTypeNormalization + extends DataNormalizationOperation { + SimpleTypeNormalization(final T identifier, final DataSchemaNode potential) { + super(identifier,potential); + } + + @Override + public DataNormalizationOperation getChild(final PathArgument child) { + return null; + } + + @Override + public DataNormalizationOperation getChild(final QName child) { + return null; + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return null; + } + + @Override + public boolean isLeaf() { + return true; + } + } + + private static final class LeafNormalization extends SimpleTypeNormalization { + LeafNormalization(final LeafSchemaNode potential) { + super(new NodeIdentifier(potential.getQName()),potential); + } + } + + private static final class LeafListEntryNormalization extends SimpleTypeNormalization { + LeafListEntryNormalization(final LeafListSchemaNode potential) { + super(new NodeWithValue(potential.getQName(), null),potential); + } + + @Override + public boolean isKeyedEntry() { + return true; + } + } + + private abstract static class CompositeNodeNormalizationOperation + extends DataNormalizationOperation { + CompositeNodeNormalizationOperation(final T identifier, final DataSchemaNode schema) { + super(identifier,schema); + } + + @Override + public boolean isLeaf() { + return false; + } + } + + private abstract static class DataContainerNormalizationOperation + extends CompositeNodeNormalizationOperation { + private final DataNodeContainer schema; + private final Map> byQName; + private final Map> byArg; + + DataContainerNormalizationOperation(final T identifier, final DataNodeContainer schema, + final DataSchemaNode node) { + super(identifier,node); + this.schema = schema; + this.byArg = new ConcurrentHashMap<>(); + this.byQName = new ConcurrentHashMap<>(); + } + + @Override + public DataNormalizationOperation getChild(final PathArgument child) throws DataNormalizationException { + DataNormalizationOperation potential = byArg.get(child); + if (potential != null) { + return potential; + } + potential = fromLocalSchema(child); + return register(potential); + } + + @Override + public DataNormalizationOperation getChild(final QName child) throws DataNormalizationException { + DataNormalizationOperation potential = byQName.get(child); + if (potential != null) { + return potential; + } + potential = fromLocalSchemaAndQName(schema, child); + return register(potential); + } + + private DataNormalizationOperation fromLocalSchema(final PathArgument child) + throws DataNormalizationException { + if (child instanceof AugmentationIdentifier) { + return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames() + .iterator().next()); + } + return fromSchemaAndQNameChecked(schema, child.getNodeType()); + } + + protected DataNormalizationOperation fromLocalSchemaAndQName(final DataNodeContainer schema2, + final QName child) throws DataNormalizationException { + return fromSchemaAndQNameChecked(schema2, child); + } + + private DataNormalizationOperation register(final DataNormalizationOperation potential) { + if (potential != null) { + byArg.put(potential.getIdentifier(), potential); + for (final QName qname : potential.getQNameIdentifiers()) { + byQName.put(qname, potential); + } + } + return potential; + } + + private static DataNormalizationOperation fromSchemaAndQNameChecked(final DataNodeContainer schema, + final QName child) throws DataNormalizationException { + + final DataSchemaNode result = findChildSchemaNode(schema, child); + if (result == null) { + throw new DataNormalizationException(String.format( + "Supplied QName %s is not valid according to schema %s, potential children nodes: %s", child, + schema,schema.getChildNodes())); + } + + // We try to look up if this node was added by augmentation + if (schema instanceof DataSchemaNode && result.isAugmenting()) { + return fromAugmentation(schema, (AugmentationTarget) schema, result); + } + return fromDataSchemaNode(result); + } + } + + private static final class ListItemNormalization extends + DataContainerNormalizationOperation { + ListItemNormalization(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) { + super(identifier, schema, schema); + } + + @Override + @SuppressFBWarnings("BC_UNCONFIRMED_CAST") + public NormalizedNode createDefault(final PathArgument currentArg) { + final DataContainerNodeBuilder builder = Builders + .mapEntryBuilder().withNodeIdentifier((NodeIdentifierWithPredicates) currentArg); + for (final Entry keyValue : ((NodeIdentifierWithPredicates) currentArg).entrySet()) { + builder.addChild(Builders.leafBuilder() + // + .withNodeIdentifier(new NodeIdentifier(keyValue.getKey())).withValue(keyValue.getValue()) + .build()); + } + return builder.build(); + } + + @Override + public boolean isKeyedEntry() { + return true; + } + } + + private static final class UnkeyedListItemNormalization + extends DataContainerNormalizationOperation { + UnkeyedListItemNormalization(final ListSchemaNode schema) { + super(new NodeIdentifier(schema.getQName()), schema,schema); + } + + @Override + @SuppressFBWarnings("BC_UNCONFIRMED_CAST") + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.unkeyedListEntryBuilder().withNodeIdentifier((NodeIdentifier) currentArg).build(); + } + } + + private static final class ContainerNormalization extends DataContainerNormalizationOperation { + ContainerNormalization(final ContainerSchemaNode schema) { + super(new NodeIdentifier(schema.getQName()),schema, schema); + } + + @Override + @SuppressFBWarnings("BC_UNCONFIRMED_CAST") + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.containerBuilder().withNodeIdentifier((NodeIdentifier) currentArg).build(); + } + } + + private abstract static class MixinNormalizationOp + extends CompositeNodeNormalizationOperation { + + MixinNormalizationOp(final T identifier, final DataSchemaNode schema) { + super(identifier,schema); + } + + @Override + public final boolean isMixin() { + return true; + } + } + + private static final class OrderedLeafListMixinNormalization extends UnorderedLeafListMixinNormalization { + OrderedLeafListMixinNormalization(final LeafListSchemaNode potential) { + super(potential); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier()).build(); + } + } + + private static class UnorderedLeafListMixinNormalization extends MixinNormalizationOp { + + private final DataNormalizationOperation innerOp; + + UnorderedLeafListMixinNormalization(final LeafListSchemaNode potential) { + super(new NodeIdentifier(potential.getQName()),potential); + innerOp = new LeafListEntryNormalization(potential); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier()).build(); + } + + @Override + public DataNormalizationOperation getChild(final PathArgument child) { + if (child instanceof NodeWithValue) { + return innerOp; + } + return null; + } + + @Override + public DataNormalizationOperation getChild(final QName child) { + if (getIdentifier().getNodeType().equals(child)) { + return innerOp; + } + return null; + } + } + + private static final class AugmentationNormalization + extends DataContainerNormalizationOperation { + + AugmentationNormalization(final AugmentationSchemaNode augmentation, final DataNodeContainer schema) { + super(augmentationIdentifierFrom(augmentation), augmentationProxy(augmentation,schema),null); + } + + private static DataNodeContainer augmentationProxy(final AugmentationSchemaNode augmentation, + final DataNodeContainer schema) { + final Set children = new HashSet<>(); + for (final DataSchemaNode augNode : augmentation.getChildNodes()) { + children.add(schema.getDataChildByName(augNode.getQName())); + } + return new EffectiveAugmentationSchema(augmentation, children); + } + + @Override + public boolean isMixin() { + return true; + } + + @Override + protected DataNormalizationOperation fromLocalSchemaAndQName(final DataNodeContainer schema, + final QName child) { + final DataSchemaNode result = findChildSchemaNode(schema, child); + if (result == null) { + return null; + } + + // We try to look up if this node was added by augmentation + if (schema instanceof DataSchemaNode && result.isAugmenting()) { + return fromAugmentation(schema, (AugmentationTarget) schema, result); + } + return fromDataSchemaNode(result); + } + + @Override + protected Set getQNameIdentifiers() { + return getIdentifier().getPossibleChildNames(); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier()).build(); + } + } + + private static class UnorderedMapMixinNormalization extends MixinNormalizationOp { + private final ListItemNormalization innerNode; + + UnorderedMapMixinNormalization(final ListSchemaNode list) { + super(new NodeIdentifier(list.getQName()),list); + this.innerNode = new ListItemNormalization(NodeIdentifierWithPredicates.of(list.getQName(), + Collections.emptyMap()), list); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.mapBuilder().withNodeIdentifier(getIdentifier()).build(); + } + + @Override + public DataNormalizationOperation getChild(final PathArgument child) { + if (child.getNodeType().equals(getIdentifier().getNodeType())) { + return innerNode; + } + return null; + } + + @Override + public DataNormalizationOperation getChild(final QName child) { + if (getIdentifier().getNodeType().equals(child)) { + return innerNode; + } + return null; + } + } + + private static class UnkeyedListMixinNormalization extends MixinNormalizationOp { + private final UnkeyedListItemNormalization innerNode; + + UnkeyedListMixinNormalization(final ListSchemaNode list) { + super(new NodeIdentifier(list.getQName()),list); + this.innerNode = new UnkeyedListItemNormalization(list); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.unkeyedListBuilder().withNodeIdentifier(getIdentifier()).build(); + } + + @Override + public DataNormalizationOperation getChild(final PathArgument child) { + if (child.getNodeType().equals(getIdentifier().getNodeType())) { + return innerNode; + } + return null; + } + + @Override + public DataNormalizationOperation getChild(final QName child) { + if (getIdentifier().getNodeType().equals(child)) { + return innerNode; + } + return null; + } + } + + private static final class OrderedMapMixinNormalization extends UnorderedMapMixinNormalization { + OrderedMapMixinNormalization(final ListSchemaNode list) { + super(list); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.orderedMapBuilder().withNodeIdentifier(getIdentifier()).build(); + } + } + + private static class ChoiceNodeNormalization extends MixinNormalizationOp { + private final ImmutableMap> byQName; + private final ImmutableMap> byArg; + + ChoiceNodeNormalization(final ChoiceSchemaNode schema) { + super(new NodeIdentifier(schema.getQName()),schema); + final ImmutableMap.Builder> byQNameBuilder = ImmutableMap.builder(); + final ImmutableMap.Builder> byArgBuilder = + ImmutableMap.builder(); + + for (final CaseSchemaNode caze : schema.getCases().values()) { + for (final DataSchemaNode cazeChild : caze.getChildNodes()) { + final DataNormalizationOperation childOp = fromDataSchemaNode(cazeChild); + byArgBuilder.put(childOp.getIdentifier(), childOp); + for (final QName qname : childOp.getQNameIdentifiers()) { + byQNameBuilder.put(qname, childOp); + } + } + } + byQName = byQNameBuilder.build(); + byArg = byArgBuilder.build(); + } + + @Override + public DataNormalizationOperation getChild(final PathArgument child) { + return byArg.get(child); + } + + @Override + public DataNormalizationOperation getChild(final QName child) { + return byQName.get(child); + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return Builders.choiceBuilder().withNodeIdentifier(getIdentifier()).build(); + } + } + + private static class AnyxmlNormalization extends DataNormalizationOperation { + AnyxmlNormalization(final AnyxmlSchemaNode schema) { + super(new NodeIdentifier(schema.getQName()), schema); + } + + @Override + public DataNormalizationOperation getChild(final PathArgument child) { + return null; + } + + @Override + public DataNormalizationOperation getChild(final QName child) { + return null; + } + + @Override + public boolean isLeaf() { + return false; + } + + @Override + public NormalizedNode createDefault(final PathArgument currentArg) { + return null; + } + } + + private static @Nullable DataSchemaNode findChildSchemaNode(final DataNodeContainer parent, final QName child) { + final DataSchemaNode potential = parent.getDataChildByName(child); + return potential != null ? potential : findChoice(parent, child); + } + + private static @Nullable ChoiceSchemaNode findChoice(final DataNodeContainer parent, final QName child) { + for (final ChoiceSchemaNode choice : Iterables.filter(parent.getChildNodes(), ChoiceSchemaNode.class)) { + for (final CaseSchemaNode caze : choice.getCases().values()) { + if (findChildSchemaNode(caze, child) != null) { + return choice; + } + } + } + return null; + } + + public static AugmentationIdentifier augmentationIdentifierFrom(final AugmentationSchemaNode augmentation) { + final ImmutableSet.Builder potentialChildren = ImmutableSet.builder(); + for (final DataSchemaNode child : augmentation.getChildNodes()) { + potentialChildren.add(child.getQName()); + } + return new AugmentationIdentifier(potentialChildren.build()); + } + + /** + * Returns a DataNormalizationOperation for provided child node. + * + *

+ * If supplied child is added by Augmentation this operation returns + * a DataNormalizationOperation for augmentation, + * otherwise returns a DataNormalizationOperation for child as + * call for {@link #fromDataSchemaNode(DataSchemaNode)}. + */ + @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", + justification = "https://github.com/spotbugs/spotbugs/issues/811") + private static DataNormalizationOperation fromAugmentation(final DataNodeContainer parent, + final AugmentationTarget parentAug, final DataSchemaNode child) { + AugmentationSchemaNode augmentation = null; + for (final AugmentationSchemaNode aug : parentAug.getAvailableAugmentations()) { + final DataSchemaNode potential = aug.getDataChildByName(child.getQName()); + if (potential != null) { + augmentation = aug; + break; + } + + } + if (augmentation != null) { + return new AugmentationNormalization(augmentation, parent); + } else { + return fromDataSchemaNode(child); + } + } + + public static DataNormalizationOperation fromDataSchemaNode(final DataSchemaNode potential) { + if (potential instanceof ContainerSchemaNode) { + return new ContainerNormalization((ContainerSchemaNode) potential); + } else if (potential instanceof ListSchemaNode) { + + return fromListSchemaNode((ListSchemaNode) potential); + } else if (potential instanceof LeafSchemaNode) { + return new LeafNormalization((LeafSchemaNode) potential); + } else if (potential instanceof ChoiceSchemaNode) { + return new ChoiceNodeNormalization((ChoiceSchemaNode) potential); + } else if (potential instanceof LeafListSchemaNode) { + return fromLeafListSchemaNode((LeafListSchemaNode) potential); + } else if (potential instanceof AnyxmlSchemaNode) { + return new AnyxmlNormalization((AnyxmlSchemaNode) potential); + } + return null; + } + + private static DataNormalizationOperation fromListSchemaNode(final ListSchemaNode potential) { + final List keyDefinition = potential.getKeyDefinition(); + if (keyDefinition == null || keyDefinition.isEmpty()) { + return new UnkeyedListMixinNormalization(potential); + } + if (potential.isUserOrdered()) { + return new OrderedMapMixinNormalization(potential); + } + return new UnorderedMapMixinNormalization(potential); + } + + private static DataNormalizationOperation fromLeafListSchemaNode(final LeafListSchemaNode potential) { + if (potential.isUserOrdered()) { + return new OrderedLeafListMixinNormalization(potential); + } + return new UnorderedLeafListMixinNormalization(potential); + } + + + public static DataNormalizationOperation from(final SchemaContext ctx) { + return new ContainerNormalization(ctx); + } + + public abstract NormalizedNode createDefault(PathArgument currentArg); +} diff --git a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizer.java b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizer.java new file mode 100644 index 0000000000..b03f860bb1 --- /dev/null +++ b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/DataNormalizer.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.sal.restconf.impl; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.collect.ImmutableList; +import java.util.Iterator; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +class DataNormalizer { + private final DataNormalizationOperation operation; + + DataNormalizer(final SchemaContext ctx) { + operation = DataNormalizationOperation.from(ctx); + } + + YangInstanceIdentifier toNormalized(final YangInstanceIdentifier legacy) { + ImmutableList.Builder normalizedArgs = ImmutableList.builder(); + + DataNormalizationOperation currentOp = operation; + Iterator arguments = legacy.getPathArguments().iterator(); + + try { + while (arguments.hasNext()) { + PathArgument legacyArg = arguments.next(); + currentOp = currentOp.getChild(legacyArg); + checkArgument(currentOp != null, + "Legacy Instance Identifier %s is not correct. Normalized Instance Identifier so far %s", + legacy, normalizedArgs.build()); + while (currentOp.isMixin()) { + normalizedArgs.add(currentOp.getIdentifier()); + currentOp = currentOp.getChild(legacyArg.getNodeType()); + } + normalizedArgs.add(legacyArg); + } + } catch (DataNormalizationException e) { + throw new IllegalArgumentException(String.format("Failed to normalize path %s", legacy), e); + } + + return YangInstanceIdentifier.create(normalizedArgs.build()); + } + + DataNormalizationOperation getOperation(final YangInstanceIdentifier legacy) + throws DataNormalizationException { + DataNormalizationOperation currentOp = operation; + + for (PathArgument pathArgument : legacy.getPathArguments()) { + currentOp = currentOp.getChild(pathArgument); + } + return currentOp; + } + + YangInstanceIdentifier toLegacy(final YangInstanceIdentifier normalized) throws DataNormalizationException { + ImmutableList.Builder legacyArgs = ImmutableList.builder(); + DataNormalizationOperation currentOp = operation; + for (PathArgument normalizedArg : normalized.getPathArguments()) { + currentOp = currentOp.getChild(normalizedArg); + if (!currentOp.isMixin()) { + legacyArgs.add(normalizedArg); + } + } + return YangInstanceIdentifier.create(legacyArgs.build()); + } + + DataNormalizationOperation getRootOperation() { + return operation; + } +} -- 2.36.6