Bug 1677 - Parser: ListSchemaNodeBuilder keys needs to be a LinkedHashSet
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / AugmentationSchemaBuilderImpl.java
1 /*
2  * Copyright (c) 2013 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.parser.builder.impl;
9
10 import static com.google.common.base.Preconditions.checkNotNull;
11
12 import com.google.common.base.Optional;
13 import com.google.common.collect.ImmutableList;
14 import java.net.URI;
15 import java.util.Date;
16 import java.util.Iterator;
17 import java.util.List;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
20 import org.opendaylight.yangtools.yang.model.api.NamespaceRevisionAware;
21 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
22 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
23 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
24 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
25 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
26 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
27 import org.opendaylight.yangtools.yang.parser.builder.api.UnknownSchemaNodeBuilder;
28 import org.opendaylight.yangtools.yang.parser.builder.util.AbstractDocumentedDataNodeContainer;
29 import org.opendaylight.yangtools.yang.parser.builder.util.AbstractDocumentedDataNodeContainerBuilder;
30
31 public final class AugmentationSchemaBuilderImpl extends AbstractDocumentedDataNodeContainerBuilder implements AugmentationSchemaBuilder {
32     private final int order;
33     private AugmentationSchemaImpl instance;
34     private String whenCondition;
35
36     private final String augmentTargetStr;
37     private final SchemaPath targetPath;
38
39     private boolean resolved;
40     private boolean unsupportedTarget = false;
41
42     private AugmentationSchemaBuilder copyOf;
43
44     public AugmentationSchemaBuilderImpl(final String moduleName, final int line, final String augmentTargetStr,
45             final SchemaPath targetPath, final int order) {
46         super(moduleName, line, null);
47         this.order = order;
48         this.augmentTargetStr = augmentTargetStr;
49         this.targetPath = targetPath;
50     }
51
52     @Override
53     protected String getStatementName() {
54         return "augment";
55     }
56
57     @Override
58     public SchemaPath getPath() {
59         return targetPath;
60     }
61
62     @Override
63     public SchemaPath getTargetPath() {
64         return targetPath;
65     }
66
67     @Override
68     public AugmentationSchema build() {
69         if (instance != null) {
70             return instance;
71         }
72
73         buildChildren();
74
75         instance = new AugmentationSchemaImpl(targetPath, order,this);
76
77         Builder parent = getParent();
78         if (parent instanceof ModuleBuilder) {
79             ModuleBuilder moduleBuilder = (ModuleBuilder) parent;
80             instance.namespace = moduleBuilder.getNamespace();
81             instance.revision = moduleBuilder.getRevision();
82         }
83
84         if (copyOf != null) {
85             instance.setCopyOf(copyOf.build());
86         }
87
88         RevisionAwareXPath whenStmt;
89         if (whenCondition == null) {
90             whenStmt = null;
91         } else {
92             whenStmt = new RevisionAwareXPathImpl(whenCondition, false);
93         }
94         instance.whenCondition = whenStmt;
95
96         // UNKNOWN NODES
97         for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
98             unknownNodes.add(b.build());
99         }
100         instance.unknownNodes = ImmutableList.copyOf(unknownNodes);
101
102         return instance;
103     }
104
105     @Override
106     public boolean isResolved() {
107         return resolved;
108     }
109
110     @Override
111     public void setResolved(final boolean resolved) {
112         this.resolved = resolved;
113     }
114
115     /**
116      *  Set true if target of augment is unsupported (e.g. node in body of extension).
117      *  In such case, augmentation is skipped and AugmentationSchema is not built.
118      */
119     @Override
120     public void setUnsupportedTarget(boolean unsupportedTarget) {
121         this.unsupportedTarget = unsupportedTarget;
122     }
123
124     /**
125      *  Return true if target of augment is unsupported (e.g. node in body of extension).
126      *  In such case, augmentation is skipped and AugmentationSchema is not built.
127      */
128     @Override
129     public boolean isUnsupportedTarget() {
130         return unsupportedTarget;
131     }
132
133     @Override
134     public String getWhenCondition() {
135         return whenCondition;
136     }
137
138     @Override
139     public void addWhenCondition(final String whenCondition) {
140         this.whenCondition = whenCondition;
141     }
142
143     @Override
144     public String getTargetPathAsString() {
145         return augmentTargetStr;
146     }
147
148     @Override
149     public int getOrder() {
150         return order;
151     }
152
153     @Override
154     public int hashCode() {
155         final int prime = 17;
156         int result = 1;
157         result = prime * result + ((augmentTargetStr == null) ? 0 : augmentTargetStr.hashCode());
158         result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode());
159         result = prime * result + getChildNodeBuilders().hashCode();
160         return result;
161     }
162
163     @Override
164     public boolean equals(final Object obj) {
165         if (this == obj) {
166             return true;
167         }
168         if (obj == null) {
169             return false;
170         }
171         if (getClass() != obj.getClass()) {
172             return false;
173         }
174         AugmentationSchemaBuilderImpl other = (AugmentationSchemaBuilderImpl) obj;
175         if (augmentTargetStr == null) {
176             if (other.augmentTargetStr != null) {
177                 return false;
178             }
179         } else if (!augmentTargetStr.equals(other.augmentTargetStr)) {
180             return false;
181         }
182         if (whenCondition == null) {
183             if (other.whenCondition != null) {
184                 return false;
185             }
186         } else if (!whenCondition.equals(other.whenCondition)) {
187             return false;
188         }
189         if (!getChildNodeBuilders().equals(other.getChildNodeBuilders())) {
190             return false;
191         }
192         return true;
193     }
194
195     @Override
196     public String toString() {
197         return "augment " + augmentTargetStr;
198     }
199
200     public void setCopyOf(final AugmentationSchemaBuilder old) {
201         copyOf = old;
202     }
203
204     private static final class AugmentationSchemaImpl extends AbstractDocumentedDataNodeContainer implements AugmentationSchema, NamespaceRevisionAware, Comparable<AugmentationSchemaImpl> {
205         private final int order;
206         private final SchemaPath targetPath;
207         private RevisionAwareXPath whenCondition;
208
209         private URI namespace;
210         private Date revision;
211         private ImmutableList<UnknownSchemaNode> unknownNodes;
212         private AugmentationSchema copyOf;
213
214         public AugmentationSchemaImpl(final SchemaPath targetPath, final int order, final AugmentationSchemaBuilderImpl builder) {
215             super(builder);
216             this.targetPath = targetPath;
217             this.order = order;
218         }
219
220         public void setCopyOf(final AugmentationSchema build) {
221             this.copyOf = build;
222         }
223
224         @Override
225         public Optional<AugmentationSchema> getOriginalDefinition() {
226             return Optional.fromNullable(this.copyOf);
227         }
228
229         @Override
230         public SchemaPath getTargetPath() {
231             return targetPath;
232         }
233
234         @Override
235         public RevisionAwareXPath getWhenCondition() {
236             return whenCondition;
237         }
238
239         @Override
240         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
241             return unknownNodes;
242         }
243
244         @Override
245         public URI getNamespace() {
246             return namespace;
247         }
248
249         @Override
250         public Date getRevision() {
251             return revision;
252         }
253
254         @Override
255         public int hashCode() {
256             final int prime = 17;
257             int result = 1;
258             result = prime * result + ((targetPath == null) ? 0 : targetPath.hashCode());
259             result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode());
260             result = prime * result + getChildNodes().hashCode();
261             return result;
262         }
263
264         @Override
265         public boolean equals(final Object obj) {
266             if (this == obj) {
267                 return true;
268             }
269             if (obj == null) {
270                 return false;
271             }
272             if (getClass() != obj.getClass()) {
273                 return false;
274             }
275             AugmentationSchemaImpl other = (AugmentationSchemaImpl) obj;
276             if (targetPath == null) {
277                 if (other.targetPath != null) {
278                     return false;
279                 }
280             } else if (!targetPath.equals(other.targetPath)) {
281                 return false;
282             }
283             if (whenCondition == null) {
284                 if (other.whenCondition != null) {
285                     return false;
286                 }
287             } else if (!whenCondition.equals(other.whenCondition)) {
288                 return false;
289             }
290             if (!getChildNodes().equals(other.getChildNodes())) {
291                 return false;
292             }
293             return true;
294         }
295
296         @Override
297         public String toString() {
298             StringBuilder sb = new StringBuilder(AugmentationSchemaImpl.class.getSimpleName());
299             sb.append("[");
300             sb.append("targetPath=").append(targetPath);
301             sb.append(", when=").append(whenCondition);
302             sb.append("]");
303             return sb.toString();
304         }
305
306         @Override
307         public int compareTo(final AugmentationSchemaImpl o) {
308             checkNotNull(o);
309             Iterator<QName> thisIt = this.targetPath.getPathFromRoot().iterator();
310             Iterator<QName> otherIt = o.getTargetPath().getPathFromRoot().iterator();
311             while (thisIt.hasNext()) {
312                 if (otherIt.hasNext()) {
313                     int comp = thisIt.next().compareTo(otherIt.next());
314                     if (comp != 0) {
315                         return comp;
316                     }
317                 } else {
318                     return 1;
319                 }
320             }
321             if (otherIt.hasNext()) {
322                 return -1;
323             }
324             return this.order - o.order;
325         }
326     }
327 }