Remove Augmentation{Identifier,Node}
[yangtools.git] / data / yang-data-tree-ri / src / main / java / org / opendaylight / yangtools / yang / data / tree / impl / MandatoryDescendant.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.tree.impl;
9
10 import static com.google.common.base.Verify.verify;
11 import static java.util.Objects.requireNonNull;
12
13 import org.eclipse.jdt.annotation.NonNull;
14 import org.eclipse.jdt.annotation.Nullable;
15 import org.opendaylight.yangtools.concepts.Immutable;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
20 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
22 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
23 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * A path to a descendant which must exist. This really should be equivalent to YangInstanceIdentifier, but for now we
29  * need to deal with up to two possible paths -- one with AugmentationIdentifiers and one without.
30  */
31 // FIXME: 8.0.0: remove this structure and just keep the 'path' YangInstanceIdentifier
32 final class MandatoryDescendant implements Immutable {
33     private static final Logger LOG = LoggerFactory.getLogger(MandatoryDescendant.class);
34
35     // Correctly-nested path, mirroring Augmentation and choice/case structure
36     private final @NonNull YangInstanceIdentifier path;
37     // Legacy trivial path,
38     private final @Nullable YangInstanceIdentifier legacyPath;
39
40     private MandatoryDescendant(final YangInstanceIdentifier path, final YangInstanceIdentifier legacyPath) {
41         this.path = requireNonNull(path);
42         this.legacyPath = legacyPath;
43     }
44
45     static @NonNull MandatoryDescendant create(final YangInstanceIdentifier parentId,
46             final DataNodeContainer parentSchema, final DataSchemaNode childSchema) {
47         return new MandatoryDescendant(parentId.node(NodeIdentifier.create(childSchema.getQName())).toOptimized(),
48             null);
49     }
50
51     void enforceOnData(final NormalizedNode data) {
52         // Find try primary path first ...
53         if (NormalizedNodes.findNode(data, path).isPresent()) {
54             return;
55         }
56         // ... if we have a legacy path, try that as well ...
57         if (legacyPath != null && NormalizedNodes.findNode(data, legacyPath).isPresent()) {
58             // .. this should not really be happening ...
59             LOG.debug("Found {} at alternate path {}", path, legacyPath);
60             return;
61         }
62
63         // ... not found, report the error
64         throw new IllegalArgumentException(String.format("Node %s is missing mandatory descendant %s",
65             data.getIdentifier(), path));
66     }
67
68     static AugmentationSchemaNode getAugIdentifierOfChild(final DataNodeContainer parent, final DataSchemaNode child) {
69         verify(parent instanceof AugmentationTarget,
70             "Unexpected augmenting child %s in non-target parent %s", child, parent);
71         return ((AugmentationTarget) parent).getAvailableAugmentations().stream()
72             .filter(augment -> augment.findDataChildByName(child.getQName()).isPresent())
73             .findFirst()
74             .orElseThrow(() -> new IllegalArgumentException(String.format(
75                 "Node %s is marked as augmenting but is not present in the schema of %s", child.getQName(), parent)));
76     }
77
78     @Override
79     public String toString() {
80         return legacyPath == null ? path.toString() : "(" + path + " || " + legacyPath + ")";
81     }
82 }