Fixup DerivedStringValidator representation checking
[yangtools.git] / yang / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / AbstractDerivedStringValidator.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.common;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.Beta;
13 import javax.annotation.concurrent.ThreadSafe;
14 import org.eclipse.jdt.annotation.NonNullByDefault;
15 import org.eclipse.jdt.annotation.Nullable;
16
17 /**
18  * Abstract base class for implementing validators.
19  *
20  * @param <R> string representation class
21  * @param <T> validated string representation class
22  * @author Robert Varga
23  */
24 @Beta
25 @NonNullByDefault
26 @ThreadSafe
27 public abstract class AbstractDerivedStringValidator<R extends DerivedString<R>, T extends R>
28         implements DerivedStringValidator<R, T> {
29     private final DerivedStringSupport<R> representationSupport;
30     private final Class<T> validatedClass;
31
32     protected AbstractDerivedStringValidator(final DerivedStringSupport<R> representationSupport,
33             final Class<T> validatedClass) {
34         this.representationSupport = requireNonNull(representationSupport);
35         this.validatedClass = DerivedString.validateValidationClass(validatedClass);
36     }
37
38     @Override
39     public final Class<R> getRepresentationClass() {
40         return representationSupport.getRepresentationClass();
41     }
42
43     @Override
44     public final Class<T> getValidatedRepresentationClass() {
45         return validatedClass;
46     }
47
48     @Override
49     public final T validateRepresentation(final R value) {
50         @Nullable T valid;
51         return (valid = castIfValid(value)) != null ? valid : validate(value);
52     }
53
54     @Override
55     public final T validateRepresentation(final R value, final String canonicalString) {
56         @Nullable T valid;
57         return (valid = castIfValid(value)) != null ? valid : validate(value, requireNonNull(canonicalString));
58     }
59
60     /**
61      * Validate a {@link DerivedString} representation. Subclasses should override this method if they can
62      * provide a validation algorithm which does not rely on canonical strings but works on representation state only.
63      *
64      * @param value Representation value
65      * @return Validated representation
66      * @throws NullPointerException if {@code value} is null
67      * @throws IllegalArgumentException if the value does not meet validation criteria.
68      */
69     protected T validate(final R value) {
70         return validate(value, value.toCanonicalString());
71     }
72
73     /**
74      * Validate a {@link DerivedString} representation. Subclasses can chose whether they operate on representation
75      * state or canonical string -- both are considered equivalent.
76      *
77      * @param value Representation value
78      * @param canonicalString Canonical string matching the representation value
79      * @return Validated representation
80      * @throws NullPointerException if {@code value} or {@code canonicalString} is null.
81      * @throws IllegalArgumentException if the value does not meet validation criteria.
82      */
83     protected abstract T validate(R value, String canonicalString);
84
85     private @Nullable T castIfValid(final R value) {
86         return validatedClass.isAssignableFrom(value.validator().getValidatedRepresentationClass())
87                 ? validatedClass.cast(value) : null;
88     }
89 }