ff444a670f629d25ad0f4e7c62ffb7a3958706ad
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / effective / type / AbstractConstraintEffectiveStatement.java
1 /**
2  * Copyright (c) 2016 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.type;
9
10 import com.google.common.collect.ImmutableList;
11 import java.util.ArrayList;
12 import java.util.List;
13 import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition;
14 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
15 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
16 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
17 import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
18 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
19 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
21 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DeclaredEffectiveStatementBase;
22 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DescriptionEffectiveStatementImpl;
23 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ErrorAppTagEffectiveStatementImpl;
24 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ErrorMessageEffectiveStatementImpl;
25 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ReferenceEffectiveStatementImpl;
26 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.effective.ModifierEffectiveStatementImpl;
27
28 abstract class AbstractConstraintEffectiveStatement<A, D extends DeclaredStatement<A>> extends
29         DeclaredEffectiveStatementBase<A, D> implements ConstraintMetaDefinition {
30     private final String description;
31     private final String reference;
32     private final String errorAppTag;
33     private final String errorMessage;
34     private final ModifierKind modifier;
35     private final A constraints;
36
37     public AbstractConstraintEffectiveStatement(final StmtContext<A, D, ?> ctx,
38             final ConstraintFactory<A> constraintFactory) {
39         super(ctx);
40         String descriptionInit = null;
41         String referenceInit = null;
42         String errorAppTagInit = null;
43         String errorMessageInit = null;
44         ModifierKind modifierInit = null;
45
46         for (final EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
47             if (stmt instanceof DescriptionEffectiveStatementImpl) {
48                 descriptionInit = ((DescriptionEffectiveStatementImpl) stmt).argument();
49             }
50             if (stmt instanceof ReferenceEffectiveStatementImpl) {
51                 referenceInit = ((ReferenceEffectiveStatementImpl) stmt).argument();
52             }
53             if (stmt instanceof ErrorAppTagEffectiveStatementImpl) {
54                 errorAppTagInit = ((ErrorAppTagEffectiveStatementImpl) stmt).argument();
55             }
56             if (stmt instanceof ErrorMessageEffectiveStatementImpl) {
57                 errorMessageInit = ((ErrorMessageEffectiveStatementImpl) stmt).argument();
58             }
59             if (stmt instanceof ModifierEffectiveStatementImpl) {
60                 modifierInit = ((ModifierEffectiveStatementImpl) stmt).argument();
61             }
62         }
63
64         this.description = descriptionInit;
65         this.reference = referenceInit;
66         this.errorAppTag = errorAppTagInit;
67         this.errorMessage = errorMessageInit;
68         this.modifier = modifierInit;
69         this.constraints = constraintFactory.createConstraints(this, super.argument());
70     }
71
72     @Override
73     public final A argument() {
74         return constraints;
75     }
76
77     public final boolean isCustomizedStatement() {
78         return this.description != null || this.reference != null || this.errorAppTag != null
79                 || this.errorMessage != null || this.modifier != null;
80     }
81
82     @Override
83     public final String getDescription() {
84         return description;
85     }
86
87     public final ModifierKind getModifier() {
88         return modifier;
89     }
90
91     @Override
92     public final String getReference() {
93         return reference;
94     }
95
96     @Override
97     public final String getErrorAppTag() {
98         return errorAppTag;
99     }
100
101     @Override
102     public final String getErrorMessage() {
103         return errorMessage;
104     }
105 }
106
107 abstract class ConstraintFactory<A> {
108     abstract protected A createConstraints(AbstractConstraintEffectiveStatement<A, ?> stmt, A argument);
109 }
110
111 abstract class ListConstraintFactory<A> extends ConstraintFactory<List<A>> {
112     @Override
113     protected List<A> createConstraints(final AbstractConstraintEffectiveStatement<List<A>, ?> stmt,
114             final List<A> argument) {
115         if (!stmt.isCustomizedStatement()) {
116             return ImmutableList.copyOf(argument);
117         }
118
119         final List<A> customizedConstraints = new ArrayList<>(argument.size());
120         for (final A constraint : argument) {
121             customizedConstraints.add(createCustomizedConstraint(constraint, stmt));
122         }
123         return ImmutableList.copyOf(customizedConstraints);
124     }
125
126     abstract protected A createCustomizedConstraint(A constraint, AbstractConstraintEffectiveStatement<List<A>, ?> stmt);
127 }
128
129 final class LengthConstraintFactory extends ListConstraintFactory<LengthConstraint> {
130     @Override
131     protected LengthConstraint createCustomizedConstraint(final LengthConstraint lengthConstraint,
132             final AbstractConstraintEffectiveStatement<List<LengthConstraint>, ?> stmt) {
133         return new LengthConstraintEffectiveImpl(lengthConstraint.getMin(), lengthConstraint.getMax(),
134                 stmt.getDescription(), stmt.getReference(), stmt.getErrorAppTag(), stmt.getErrorMessage());
135     }
136 }
137
138 final class RangeConstraintFactory extends ListConstraintFactory<RangeConstraint> {
139     @Override
140     protected RangeConstraint createCustomizedConstraint(final RangeConstraint rangeConstraint,
141             final AbstractConstraintEffectiveStatement<List<RangeConstraint>, ?> stmt) {
142         return new RangeConstraintEffectiveImpl(rangeConstraint.getMin(), rangeConstraint.getMax(),
143                 stmt.getDescription(), stmt.getReference(), stmt.getErrorAppTag(), stmt.getErrorMessage());
144     }
145 }
146
147 final class PatternConstraintFactory extends ConstraintFactory<PatternConstraint> {
148     @Override
149     protected PatternConstraint createConstraints(
150             final AbstractConstraintEffectiveStatement<PatternConstraint, ?> stmt, final PatternConstraint argument) {
151         if (!stmt.isCustomizedStatement()) {
152             return argument;
153         }
154
155         return createCustomizedConstraint(argument, stmt);
156     }
157
158     private static PatternConstraint createCustomizedConstraint(final PatternConstraint patternConstraint,
159             final AbstractConstraintEffectiveStatement<?, ?> stmt) {
160         return new PatternConstraintEffectiveImpl(patternConstraint.getRegularExpression(),
161                 patternConstraint.getRawRegularExpression(), stmt.getDescription(), stmt.getReference(),
162                 stmt.getErrorAppTag(), stmt.getErrorMessage(), stmt.getModifier());
163     }
164 }