Centralize must contraint definitions
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / leaf / LeafEffectiveStatementImpl.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.rfc7950.stmt.leaf;
9
10 import java.util.Objects;
11 import java.util.Optional;
12 import org.opendaylight.yangtools.yang.common.QName;
13 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
14 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
15 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
16 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
17 import org.opendaylight.yangtools.yang.model.api.stmt.DefaultEffectiveStatement;
18 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement;
19 import org.opendaylight.yangtools.yang.model.api.stmt.LeafEffectiveStatement;
20 import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
21 import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryEffectiveStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.UnitsEffectiveStatement;
26 import org.opendaylight.yangtools.yang.model.util.type.ConcreteTypeBuilder;
27 import org.opendaylight.yangtools.yang.model.util.type.ConcreteTypes;
28 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveMustConstraintAwareDataSchemaNode;
29 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStmtUtils;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
31 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
32
33 /**
34  * Internal implementation of LeafEffectiveStatement.
35  *
36  * @deprecated This class is visible only for historical purposes and is going to be hidden.
37  */
38 // FIXME: 4.0.0: hide this class
39 @Deprecated
40 public final class LeafEffectiveStatementImpl extends AbstractEffectiveMustConstraintAwareDataSchemaNode<LeafStatement>
41         implements LeafEffectiveStatement, LeafSchemaNode, DerivableSchemaNode {
42     private final LeafSchemaNode original;
43     private final TypeDefinition<?> type;
44     private final String defaultStr;
45     private final String unitsStr;
46     private final boolean mandatory;
47
48     LeafEffectiveStatementImpl(final StmtContext<QName, LeafStatement, EffectiveStatement<QName, LeafStatement>> ctx) {
49         super(ctx);
50         this.original = (LeafSchemaNode) ctx.getOriginalCtx().map(StmtContext::buildEffective).orElse(null);
51
52         final TypeEffectiveStatement<?> typeStmt = SourceException.throwIfNull(
53                 firstSubstatementOfType(TypeEffectiveStatement.class), ctx.getStatementSourceReference(),
54                 "Leaf is missing a 'type' statement");
55
56         String dflt = null;
57         String units = null;
58         final ConcreteTypeBuilder<?> builder = ConcreteTypes.concreteTypeBuilder(typeStmt.getTypeDefinition(),
59             ctx.getSchemaPath().get());
60         for (final EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
61             if (stmt instanceof DefaultEffectiveStatement) {
62                 dflt = ((DefaultEffectiveStatement)stmt).argument();
63                 builder.setDefaultValue(stmt.argument());
64             } else if (stmt instanceof DescriptionEffectiveStatement) {
65                 builder.setDescription(((DescriptionEffectiveStatement)stmt).argument());
66             } else if (stmt instanceof ReferenceEffectiveStatement) {
67                 builder.setReference(((ReferenceEffectiveStatement)stmt).argument());
68             } else if (stmt instanceof StatusEffectiveStatement) {
69                 builder.setStatus(((StatusEffectiveStatement)stmt).argument());
70             } else if (stmt instanceof UnitsEffectiveStatement) {
71                 units = ((UnitsEffectiveStatement)stmt).argument();
72                 builder.setUnits(units);
73             }
74         }
75
76         SourceException.throwIf(
77             EffectiveStmtUtils.hasDefaultValueMarkedWithIfFeature(ctx.getRootVersion(), typeStmt, dflt),
78             ctx.getStatementSourceReference(),
79             "Leaf '%s' has default value '%s' marked with an if-feature statement.", ctx.getStatementArgument(), dflt);
80
81         defaultStr = dflt;
82         unitsStr = units;
83         type = builder.build();
84         mandatory = findFirstEffectiveSubstatementArgument(MandatoryEffectiveStatement.class).orElse(Boolean.FALSE)
85                 .booleanValue();
86     }
87
88     @Override
89     public boolean isMandatory() {
90         return mandatory;
91     }
92
93     @Override
94     public Optional<LeafSchemaNode> getOriginal() {
95         return Optional.ofNullable(original);
96     }
97
98     @Override
99     public TypeDefinition<?> getType() {
100         return type;
101     }
102
103     @Override
104     public int hashCode() {
105         final int prime = 31;
106         int result = 1;
107         result = prime * result + Objects.hashCode(getQName());
108         result = prime * result + Objects.hashCode(getPath());
109         return result;
110     }
111
112     @Override
113     public boolean equals(final Object obj) {
114         if (this == obj) {
115             return true;
116         }
117         if (!(obj instanceof LeafEffectiveStatementImpl)) {
118             return false;
119         }
120         final LeafEffectiveStatementImpl other = (LeafEffectiveStatementImpl) obj;
121         return Objects.equals(getQName(), other.getQName()) && Objects.equals(getPath(), other.getPath());
122     }
123
124     @Override
125     public String toString() {
126         return LeafEffectiveStatementImpl.class.getSimpleName() + "["
127                 + "qname=" + getQName()
128                 + ", path=" + getPath()
129                 + "]";
130     }
131 }