Move LeafRefPath creation from fast path
[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
17 // FIXME: 3.0.0 hide this class
18 public final class LeafRefContext {
19
20     private final QName currentNodeQName;
21     private final SchemaPath currentNodePath;
22     private final SchemaContext schemaContext;
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 Map<QName, LeafRefContext> referencingChilds;
33     private final Map<QName, LeafRefContext> referencedByChilds;
34     private final Map<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         this.currentNodeQName = leafRefContextBuilder.getCurrentNodeQName();
43         this.currentNodePath = leafRefContextBuilder.getCurrentNodePath();
44         this.schemaContext = leafRefContextBuilder.getSchemaContext();
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     SchemaContext getSchemaContext() {
117         return schemaContext;
118     }
119
120     public LeafRefPath getAbsoluteLeafRefTargetPath() {
121         return absoluteLeafRefTargetPath;
122     }
123
124     public Module getLeafRefContextModule() {
125         return module;
126     }
127
128     public LeafRefContext getReferencedByLeafRefCtxByName(final QName qname) {
129         return referencedByLeafRefCtx.get(qname);
130     }
131
132     public Map<QName, LeafRefContext> getAllReferencedByLeafRefCtxs() {
133         return referencedByLeafRefCtx;
134     }
135
136     LeafRefPath getLeafRefNodePath() {
137         LeafRefPath ret = leafRefNodePath;
138         if (ret == null) {
139             synchronized (this) {
140                 ret = leafRefNodePath;
141                 if (ret == null) {
142                     ret = leafRefNodePath = LeafRefUtils.schemaPathToLeafRefPath(currentNodePath, module);
143                 }
144             }
145         }
146         return ret;
147     }
148 }