2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
10 import com.google.common.base.Optional;
11 import com.google.common.collect.ImmutableList;
12 import java.util.Collection;
13 import java.util.HashSet;
14 import java.util.LinkedList;
15 import java.util.List;
16 import java.util.Objects;
18 import javax.annotation.Nonnull;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.UniqueConstraint;
24 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
30 public final class ListEffectiveStatementImpl extends AbstractEffectiveSimpleDataNodeContainer<ListStatement> implements
31 ListSchemaNode, DerivableSchemaNode {
32 private static final String ORDER_BY_USER_KEYWORD = "user";
34 private final boolean userOrdered;
35 private final List<QName> keyDefinition;
36 private final ListSchemaNode original;
37 private final Collection<UniqueConstraint> uniqueConstraints;
39 public ListEffectiveStatementImpl(
40 final StmtContext<QName, ListStatement, EffectiveStatement<QName, ListStatement>> ctx) {
43 this.original = ctx.getOriginalCtx() == null ? null : (ListSchemaNode) ctx.getOriginalCtx().buildEffective();
45 OrderedByEffectiveStatementImpl orderedByStmt = firstEffective(OrderedByEffectiveStatementImpl.class);
46 if (orderedByStmt != null && ORDER_BY_USER_KEYWORD.equals(orderedByStmt.argument())) {
47 this.userOrdered = true;
49 this.userOrdered = false;
53 List<QName> keyDefinitionInit = new LinkedList<>();
54 KeyEffectiveStatementImpl keyEffectiveSubstatement = firstEffective(KeyEffectiveStatementImpl.class);
56 if (keyEffectiveSubstatement != null) {
57 Set<QName> possibleLeafQNamesForKey = new HashSet<>();
59 for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
60 if (effectiveStatement instanceof LeafSchemaNode) {
61 possibleLeafQNamesForKey.add(((LeafSchemaNode) effectiveStatement).getQName());
65 for (SchemaNodeIdentifier key : keyEffectiveSubstatement.argument()) {
66 final QName keyQName = key.getLastComponent();
68 if (!possibleLeafQNamesForKey.contains(keyQName)) {
69 throw new InferenceException(ctx.getStatementSourceReference(),
70 "Key '%s' misses node '%s' in list '%s'", keyEffectiveSubstatement.getDeclared().rawArgument(),
71 keyQName.getLocalName(), ctx.getStatementArgument());
74 keyDefinitionInit.add(keyQName);
78 this.keyDefinition = ImmutableList.copyOf(keyDefinitionInit);
79 this.uniqueConstraints = ImmutableList.copyOf(allSubstatementsOfType(UniqueConstraint.class));
83 public Optional<ListSchemaNode> getOriginal() {
84 return Optional.fromNullable(original);
88 public List<QName> getKeyDefinition() {
94 public Collection<UniqueConstraint> getUniqueConstraints() {
95 return uniqueConstraints;
99 public boolean isUserOrdered() {
104 public int hashCode() {
105 final int prime = 31;
107 result = prime * result + Objects.hashCode(getQName());
108 result = prime * result + Objects.hashCode(getPath());
113 public boolean equals(final Object obj) {
120 if (getClass() != obj.getClass()) {
123 final ListEffectiveStatementImpl other = (ListEffectiveStatementImpl) obj;
124 return Objects.equals(getQName(), other.getQName()) && Objects.equals(getPath(), other.getPath());
128 public String toString() {
129 return "list " + getQName().getLocalName();