Bug 4412: New yang parser effective statements cleanup
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / effective / AugmentEffectiveStatementImpl.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.parser.stmt.rfc6020.effective;
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.Collection;
16 import java.util.Date;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Objects;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.common.QNameModule;
22 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
23 import org.opendaylight.yangtools.yang.model.api.NamespaceRevisionAware;
24 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
25 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
26 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
28 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
29 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
31 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
32
33 public final class AugmentEffectiveStatementImpl extends
34         AbstractEffectiveDocumentedDataNodeContainer<SchemaNodeIdentifier, AugmentStatement> implements
35         AugmentationSchema, NamespaceRevisionAware, Comparable<AugmentEffectiveStatementImpl> {
36     private final SchemaPath targetPath;
37     private final URI namespace;
38     private final Date revision;
39     private final int order;
40     private final List<UnknownSchemaNode> unknownNodes;
41     private final RevisionAwareXPath whenCondition;
42     private final AugmentationSchema copyOf;
43
44     public AugmentEffectiveStatementImpl(
45             final StmtContext<SchemaNodeIdentifier, AugmentStatement, EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>> ctx) {
46         super(ctx);
47
48         this.targetPath = ctx.getStatementArgument().asSchemaPath();
49
50         QNameModule rootModuleQName = Utils.getRootModuleQName(ctx);
51         this.namespace = rootModuleQName.getNamespace();
52         this.revision = rootModuleQName.getRevision();
53
54         this.order = ctx.getOrder();
55         this.copyOf = ctx.getOriginalCtx() == null ? null : (AugmentationSchema) ctx.getOriginalCtx().buildEffective();
56
57         WhenEffectiveStatementImpl whenStmt = firstEffective(WhenEffectiveStatementImpl.class);
58         this.whenCondition = (whenStmt == null) ? null : whenStmt.argument();
59
60         // initSubstatementCollections
61         Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
62         ImmutableList.Builder<UnknownSchemaNode> listBuilder = new ImmutableList.Builder<>();
63         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements) {
64             if (effectiveStatement instanceof UnknownSchemaNode) {
65                 listBuilder.add((UnknownSchemaNode) effectiveStatement);
66             }
67         }
68         this.unknownNodes = listBuilder.build();
69     }
70
71     @Override
72     public Optional<AugmentationSchema> getOriginalDefinition() {
73         return Optional.fromNullable(this.copyOf);
74     }
75
76     @Override
77     public SchemaPath getTargetPath() {
78         return targetPath;
79     }
80
81     @Override
82     public RevisionAwareXPath getWhenCondition() {
83         return whenCondition;
84     }
85
86     @Override
87     public List<UnknownSchemaNode> getUnknownSchemaNodes() {
88         return unknownNodes;
89     }
90
91     @Override
92     public URI getNamespace() {
93         return namespace;
94     }
95
96     @Override
97     public Date getRevision() {
98         return revision;
99     }
100
101     @Override
102     public int hashCode() {
103         final int prime = 17;
104         int result = 1;
105         result = prime * result + Objects.hashCode(targetPath);
106         result = prime * result + Objects.hashCode(whenCondition);
107         result = prime * result + getChildNodes().hashCode();
108         return result;
109     }
110
111     @Override
112     public boolean equals(final Object obj) {
113         if (this == obj) {
114             return true;
115         }
116         if (obj == null) {
117             return false;
118         }
119         if (getClass() != obj.getClass()) {
120             return false;
121         }
122         AugmentEffectiveStatementImpl other = (AugmentEffectiveStatementImpl) obj;
123         if (!Objects.equals(targetPath, other.targetPath)) {
124             return false;
125         }
126         if (!Objects.equals(whenCondition, other.whenCondition)) {
127             return false;
128         }
129         if (!getChildNodes().equals(other.getChildNodes())) {
130             return false;
131         }
132         return true;
133     }
134
135     @Override
136     public String toString() {
137         StringBuilder sb = new StringBuilder(AugmentEffectiveStatementImpl.class.getSimpleName());
138         sb.append("[");
139         sb.append("targetPath=").append(targetPath);
140         sb.append(", when=").append(whenCondition);
141         sb.append("]");
142         return sb.toString();
143     }
144
145     @Override
146     public int compareTo(final AugmentEffectiveStatementImpl o) {
147         checkNotNull(o);
148         Iterator<QName> thisIt = this.targetPath.getPathFromRoot().iterator();
149         Iterator<QName> otherIt = o.getTargetPath().getPathFromRoot().iterator();
150         while (thisIt.hasNext()) {
151             if (otherIt.hasNext()) {
152                 int comp = thisIt.next().compareTo(otherIt.next());
153                 if (comp != 0) {
154                     return comp;
155                 }
156             } else {
157                 return 1;
158             }
159         }
160         if (otherIt.hasNext()) {
161             return -1;
162         }
163         return this.order - o.order;
164     }
165 }