Bug 5200: Yang parser doesn't fill error-app-tag and error-message in constraints
[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.meta.DeclaredStatement;
14 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
15 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
16 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
17 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
18 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
19 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DeclaredEffectiveStatementBase;
20 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DescriptionEffectiveStatementImpl;
21 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ErrorAppTagEffectiveStatementImpl;
22 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ErrorMessageEffectiveStatementImpl;
23 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ReferenceEffectiveStatementImpl;
24
25 abstract class AbstractConstraintEffectiveStatement<A, D extends DeclaredStatement<A>> extends
26         DeclaredEffectiveStatementBase<A, D> {
27     private final String description;
28     private final String reference;
29     private final String errorAppTag;
30     private final String errorMessage;
31     private final A constraints;
32
33     public AbstractConstraintEffectiveStatement(final StmtContext<A, D, ?> ctx, ConstraintFactory<A> constraintFactory) {
34         super(ctx);
35         String descriptionInit = null;
36         String referenceInit = null;
37         String errorAppTagInit = null;
38         String errorMessageInit = null;
39
40         for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
41             if (stmt instanceof DescriptionEffectiveStatementImpl) {
42                 descriptionInit = ((DescriptionEffectiveStatementImpl) stmt).argument();
43             }
44             if (stmt instanceof ReferenceEffectiveStatementImpl) {
45                 referenceInit = ((ReferenceEffectiveStatementImpl) stmt).argument();
46             }
47             if (stmt instanceof ErrorAppTagEffectiveStatementImpl) {
48                 errorAppTagInit = ((ErrorAppTagEffectiveStatementImpl) stmt).argument();
49             }
50             if (stmt instanceof ErrorMessageEffectiveStatementImpl) {
51                 errorMessageInit = ((ErrorMessageEffectiveStatementImpl) stmt).argument();
52             }
53         }
54
55         this.description = descriptionInit;
56         this.reference = referenceInit;
57         this.errorAppTag = errorAppTagInit;
58         this.errorMessage = errorMessageInit;
59         this.constraints = constraintFactory.createConstraints(this, super.argument());
60     }
61
62     @Override
63     public final A argument() {
64         return constraints;
65     }
66
67     public final boolean isCustomizedStatement() {
68         return this.description != null || this.reference != null || this.errorAppTag != null
69                 || this.errorMessage != null;
70     }
71
72     public final String getDescription() {
73         return description;
74     }
75
76     public final String getReference() {
77         return reference;
78     }
79
80     public final String getErrorAppTag() {
81         return errorAppTag;
82     }
83
84     public final String getErrorMessage() {
85         return errorMessage;
86     }
87 }
88
89 abstract class ConstraintFactory<A> {
90     abstract protected A createConstraints(AbstractConstraintEffectiveStatement<A, ?> stmt, A argument);
91 }
92
93 abstract class ListConstraintFactory<A> extends ConstraintFactory<List<A>> {
94     @Override
95     protected List<A> createConstraints(AbstractConstraintEffectiveStatement<List<A>, ?> stmt, List<A> argument) {
96         if (!stmt.isCustomizedStatement()) {
97             return ImmutableList.copyOf(argument);
98         }
99
100         List<A> customizedConstraints = new ArrayList<>();
101         for (A constraint : argument) {
102             customizedConstraints.add(createCustomizedConstraint(constraint, stmt));
103         }
104         return customizedConstraints;
105     }
106
107     abstract protected A createCustomizedConstraint(A constraint, AbstractConstraintEffectiveStatement<List<A>, ?> stmt);
108 }
109
110 final class LengthConstraintFactory extends ListConstraintFactory<LengthConstraint> {
111     @Override
112     protected LengthConstraint createCustomizedConstraint(LengthConstraint lengthConstraint,
113             AbstractConstraintEffectiveStatement<List<LengthConstraint>, ?> stmt) {
114         return new LengthConstraintEffectiveImpl(lengthConstraint.getMin(), lengthConstraint.getMax(),
115                 stmt.getDescription(), stmt.getReference(), stmt.getErrorAppTag(), stmt.getErrorMessage());
116     }
117 }
118
119 final class RangeConstraintFactory extends ListConstraintFactory<RangeConstraint> {
120     @Override
121     protected RangeConstraint createCustomizedConstraint(RangeConstraint rangeConstraint,
122             AbstractConstraintEffectiveStatement<List<RangeConstraint>, ?> stmt) {
123         return new RangeConstraintEffectiveImpl(rangeConstraint.getMin(), rangeConstraint.getMax(),
124                 stmt.getDescription(), stmt.getReference(), stmt.getErrorAppTag(), stmt.getErrorMessage());
125     }
126 }
127
128 final class PatternConstraintFactory extends ConstraintFactory<PatternConstraint> {
129     @Override
130     protected PatternConstraint createConstraints(AbstractConstraintEffectiveStatement<PatternConstraint, ?> stmt, PatternConstraint argument) {
131         if (!stmt.isCustomizedStatement()) {
132             return argument;
133         } else {
134             return createCustomizedConstraint(argument, stmt);
135         }
136     }
137
138     private PatternConstraint createCustomizedConstraint(PatternConstraint patternConstraint,
139             AbstractConstraintEffectiveStatement<?, ?> stmt) {
140         return new PatternConstraintEffectiveImpl(patternConstraint.getRegularExpression(), stmt.getDescription(),
141                 stmt.getReference(), stmt.getErrorAppTag(), stmt.getErrorMessage());
142     }
143 }