Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / leafref / LeafRefContext.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.impl.leafref;
9
10 import com.google.common.collect.ImmutableMap;
11 import java.util.Map;
12 import org.opendaylight.yangtools.yang.common.QName;
13 import org.opendaylight.yangtools.yang.model.api.Module;
14 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
15 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
16 import org.opendaylight.yangtools.yang.model.util.AbstractSchemaContextProvider;
17
18 // FIXME: 5.0.0 hide this class
19 public final class LeafRefContext extends AbstractSchemaContextProvider {
20
21     private final QName currentNodeQName;
22     private final SchemaPath currentNodePath;
23     private final Module module;
24
25     private final LeafRefPath leafRefTargetPath;
26     private final LeafRefPath absoluteLeafRefTargetPath;
27     private final String leafRefTargetPathString;
28
29     private final boolean isReferencedBy;
30     private final boolean isReferencing;
31
32     private final ImmutableMap<QName, LeafRefContext> referencingChilds;
33     private final ImmutableMap<QName, LeafRefContext> referencedByChilds;
34     private final ImmutableMap<QName, LeafRefContext> referencedByLeafRefCtx;
35
36     // FIXME: this looks like it's related to absoluteLeafRefTargetPath, but the original use in LeafRefValidation
37     //        fast path did not make it clear. Analyze the relationship between this field and
38     //        absoluteLeafRefTargetPath.
39     private volatile LeafRefPath leafRefNodePath = null;
40
41     LeafRefContext(final LeafRefContextBuilder leafRefContextBuilder) {
42         super(leafRefContextBuilder.getSchemaContext());
43         this.currentNodeQName = leafRefContextBuilder.getCurrentNodeQName();
44         this.currentNodePath = leafRefContextBuilder.getCurrentNodePath();
45         this.leafRefTargetPath = leafRefContextBuilder.getLeafRefTargetPath();
46         this.absoluteLeafRefTargetPath = leafRefContextBuilder.getAbsoluteLeafRefTargetPath();
47         this.leafRefTargetPathString = leafRefContextBuilder.getLeafRefTargetPathString();
48         this.isReferencedBy = leafRefContextBuilder.isReferencedBy();
49         this.isReferencing = leafRefContextBuilder.isReferencing();
50         this.referencingChilds = ImmutableMap.copyOf(leafRefContextBuilder.getReferencingChilds());
51         this.referencedByChilds = ImmutableMap.copyOf(leafRefContextBuilder.getReferencedByChilds());
52         this.referencedByLeafRefCtx = ImmutableMap.copyOf(leafRefContextBuilder.getAllReferencedByLeafRefCtxs());
53         this.module = leafRefContextBuilder.getLeafRefContextModule();
54     }
55
56     public static LeafRefContext create(final SchemaContext ctx) {
57         try {
58             return new LeafRefContextTreeBuilder(ctx).buildLeafRefContextTree();
59         } catch (LeafRefYangSyntaxErrorException e) {
60             throw new IllegalArgumentException(e);
61         }
62     }
63
64     public boolean hasLeafRefContextChild() {
65         return hasReferencedChild() || hasReferencingChild();
66     }
67
68     public boolean hasReferencedChild() {
69         return !referencedByChilds.isEmpty();
70     }
71
72     public boolean hasReferencingChild() {
73         return !referencingChilds.isEmpty();
74     }
75
76     public boolean isReferenced() {
77         return isReferencedBy;
78     }
79
80     public boolean isReferencing() {
81         return isReferencing;
82     }
83
84     public LeafRefContext getReferencingChildByName(final QName name) {
85         return referencingChilds.get(name);
86     }
87
88     public Map<QName, LeafRefContext> getReferencingChilds() {
89         return referencingChilds;
90     }
91
92     public LeafRefContext getReferencedChildByName(final QName name) {
93         return referencedByChilds.get(name);
94     }
95
96     public Map<QName, LeafRefContext> getReferencedByChilds() {
97         return referencedByChilds;
98     }
99
100     public SchemaPath getCurrentNodePath() {
101         return currentNodePath;
102     }
103
104     public LeafRefPath getLeafRefTargetPath() {
105         return leafRefTargetPath;
106     }
107
108     public String getLeafRefTargetPathString() {
109         return leafRefTargetPathString;
110     }
111
112     public QName getNodeName() {
113         return currentNodeQName;
114     }
115
116     public LeafRefPath getAbsoluteLeafRefTargetPath() {
117         return absoluteLeafRefTargetPath;
118     }
119
120     public Module getLeafRefContextModule() {
121         return module;
122     }
123
124     public LeafRefContext getReferencedByLeafRefCtxByName(final QName qname) {
125         return referencedByLeafRefCtx.get(qname);
126     }
127
128     public Map<QName, LeafRefContext> getAllReferencedByLeafRefCtxs() {
129         return referencedByLeafRefCtx;
130     }
131
132     LeafRefPath getLeafRefNodePath() {
133         LeafRefPath ret = leafRefNodePath;
134         if (ret == null) {
135             synchronized (this) {
136                 ret = leafRefNodePath;
137                 if (ret == null) {
138                     ret = leafRefNodePath = LeafRefUtils.schemaPathToLeafRefPath(currentNodePath, module);
139                 }
140             }
141         }
142         return ret;
143     }
144 }