b3d864f471f9f114d648b50d4252c8c85351a3be
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / AbstractEffectiveOperationDefinition.java
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.rfc7950.stmt;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.MoreObjects;
12 import com.google.common.base.Verify;
13 import com.google.common.collect.ImmutableSet;
14 import java.util.HashSet;
15 import java.util.LinkedHashSet;
16 import java.util.Objects;
17 import java.util.Set;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
20 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
21 import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
22 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
23 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
24 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement;
27 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
29
30 @Beta
31 public abstract class AbstractEffectiveOperationDefinition<D extends DeclaredStatement<QName>>
32         extends AbstractEffectiveSchemaNode<D> implements OperationDefinition {
33     private final ImmutableSet<TypeDefinition<?>> typeDefinitions;
34     private final ImmutableSet<GroupingDefinition> groupings;
35     private final ContainerSchemaNode input;
36     private final ContainerSchemaNode output;
37
38     protected AbstractEffectiveOperationDefinition(final StmtContext<QName, D, ?> ctx) {
39         super(ctx);
40         input = findAsContainer(this, InputEffectiveStatement.class);
41         output = findAsContainer(this, OutputEffectiveStatement.class);
42
43         // initSubstatements
44         final Set<GroupingDefinition> groupingsInit = new HashSet<>();
45         final Set<TypeDefinition<?>> mutableTypeDefinitions = new LinkedHashSet<>();
46         for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
47             if (effectiveStatement instanceof GroupingDefinition
48                     && !groupingsInit.add((GroupingDefinition) effectiveStatement)) {
49                 throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement);
50             }
51             if (effectiveStatement instanceof TypedefEffectiveStatement) {
52                 final TypeDefinition<?> type = ((TypedefEffectiveStatement) effectiveStatement).getTypeDefinition();
53                 if (!mutableTypeDefinitions.add(type)) {
54                     throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement);
55                 }
56             }
57         }
58         this.groupings = ImmutableSet.copyOf(groupingsInit);
59         this.typeDefinitions = ImmutableSet.copyOf(mutableTypeDefinitions);
60     }
61
62     private static ContainerSchemaNode findAsContainer(final EffectiveStatement<?, ?> parent,
63             final Class<? extends EffectiveStatement<QName, ?>> statementType) {
64         final EffectiveStatement<?, ?> statement = parent.findFirstEffectiveSubstatement(statementType).get();
65         Verify.verify(statement instanceof ContainerSchemaNode, "Child statement %s is not a ContainerSchemaNode");
66         return (ContainerSchemaNode) statement;
67     }
68
69     @Override
70     public final ContainerSchemaNode getInput() {
71         return input;
72     }
73
74     @Override
75     public final ContainerSchemaNode getOutput() {
76         return output;
77     }
78
79     @Override
80     public final Set<TypeDefinition<?>> getTypeDefinitions() {
81         return typeDefinitions;
82     }
83
84     @Override
85     public final Set<GroupingDefinition> getGroupings() {
86         return groupings;
87     }
88
89     @Override
90     public final int hashCode() {
91         return Objects.hash(getQName(), getPath());
92     }
93
94     @Override
95     public final boolean equals(final Object obj) {
96         if (this == obj) {
97             return true;
98         }
99         if (obj == null || getClass() != obj.getClass()) {
100             return false;
101         }
102         final AbstractEffectiveOperationDefinition<?> other =
103                 (AbstractEffectiveOperationDefinition<?>) obj;
104         return Objects.equals(getQName(), other.getQName()) && Objects.equals(getPath(), other.getPath());
105     }
106
107     @Override
108     public final String toString() {
109         return MoreObjects.toStringHelper(this).add("qname", getQName()).add("path", getPath()).add("input", input)
110                 .add("output", output).toString();
111     }
112 }