Refactor ModificationApplyOperation
[yangtools.git] / data / yang-data-tree-ri / src / main / java / org / opendaylight / yangtools / yang / data / tree / impl / AbstractDataTreeTip.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. 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 org.eclipse.jdt.annotation.NonNull;
11 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
12 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateTip;
13 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
14 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeTip;
15 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
16 import org.opendaylight.yangtools.yang.data.tree.impl.node.TreeNode;
17
18 abstract class AbstractDataTreeTip implements DataTreeTip {
19     /**
20      * Return the current root node of this tip.
21      *
22      * @return Current tip root node, may not be null.
23      */
24     protected abstract @NonNull TreeNode getTipRoot();
25
26     abstract @NonNull YangInstanceIdentifier getRootPath();
27
28     @Override
29     public final void validate(final DataTreeModification modification) throws DataValidationFailedException {
30         final var m = accessMod(modification, "validate");
31         m.getStrategy().checkApplicable(new ModificationPath(getRootPath()), m.getRootModification(), getTipRoot(),
32             m.getVersion());
33     }
34
35     @Override
36     public final DataTreeCandidateTip prepare(final DataTreeModification modification) {
37         final var m = accessMod(modification, "prepare");
38         final var root = m.getRootModification();
39
40         final var currentRoot = getTipRoot();
41         if (root.getOperation() == LogicalOperation.NONE) {
42             return new NoopDataTreeCandidate(YangInstanceIdentifier.of(), root, currentRoot);
43         }
44
45         final var newRoot = m.getStrategy().apply(m.getRootModification(), currentRoot, m.getVersion())
46             .orElseThrow(() -> new IllegalStateException(
47                 "Apply strategy failed to produce root node for modification " + modification));
48         return new InMemoryDataTreeCandidate(YangInstanceIdentifier.of(), root, currentRoot, newRoot);
49     }
50
51     private static @NonNull InMemoryDataTreeModification accessMod(final DataTreeModification mod, final String op) {
52         if (mod instanceof InMemoryDataTreeModification inMemoryMod) {
53             if (inMemoryMod.isSealed()) {
54                 return inMemoryMod;
55             }
56             throw new IllegalArgumentException("Attempted to " + op + " unsealed modification " + inMemoryMod);
57         }
58         throw new IllegalArgumentException("Invalid modification " + mod.getClass());
59     }
60 }