001/*
002 * Copyright 2023 the original author or authors.
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * https://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.tools.formatting.template;
017
018import static java.util.Objects.requireNonNull;
019
020import java.io.Serializable;
021
022import de.cuioss.tools.formatting.template.lexer.Lexer;
023import de.cuioss.tools.formatting.template.lexer.LexerBuilder;
024import lombok.NoArgsConstructor;
025
026/**
027 *
028 * @param <F> at least {@link FormatterSupport}
029 */
030public class Validator<F extends FormatterSupport> implements Serializable {
031
032    private static final long serialVersionUID = 8358892211840118282L;
033
034    private final Lexer<F> lexer;
035
036    Validator(final Lexer<F> lexer) {
037        this.lexer = requireNonNull(lexer);
038    }
039
040    /**
041     * @param template must not be null if template doesn't fit to el-expression or
042     *                 use tokens which are not supported.
043     */
044    public void validate(final String template) {
045        requireNonNull(template, "Template must not be null.");
046        lexer.validateTemplate(template);
047    }
048
049    /**
050     * @return an {@link ValidatorBuilder}
051     */
052    public static <E extends FormatterSupport> ValidatorBuilder<E> builder() {
053        return new ValidatorBuilder<>();
054    }
055
056    /**
057     * This method provide only validation of simple expression language with
058     * squared brackets. If some other expression language is used on the template
059     * validation will fail. If there is a need for usage of other expression
060     * language use {@link #validateTemplate(String, Lexer)}
061     *
062     * @param template input which should be validated
063     * @param source   source must not be null
064     */
065    public static <E extends FormatterSupport> void validateTemplate(final String template, final E source) {
066        new Validator.ValidatorBuilder<E>().forSource(source).validate(template);
067    }
068
069    /**
070     * This method provide only validation of simple expression language with
071     * squared brackets. If some other expression language is used on the template
072     * validation will fail. If there is a need for usage of other expression
073     * language use {@link #validateTemplate(String, Lexer)}
074     *
075     * @param template input which should be validated
076     * @param source   target type must not be null
077     */
078    public static <E extends FormatterSupport> void validateTemplate(final String template, final Class<E> source) {
079        new Validator.ValidatorBuilder<E>().forType(source).validate(template);
080    }
081
082    /**
083     * This method provide validation for template of specific expression language.
084     * Therefore, you need to provide a fitting Lexer.
085     *
086     * @param template input which should be validated
087     * @param lexer    {@link Lexer} for usage of specific expression language on
088     *                 template
089     */
090    public static <E extends FormatterSupport> void validateTemplate(final String template, final Lexer<E> lexer) {
091        new Validator.ValidatorBuilder<E>().withLexer(lexer).validate(template);
092    }
093
094    @NoArgsConstructor
095    public static final class ValidatorBuilder<E extends FormatterSupport> {
096
097        private Lexer<E> lexer;
098
099        public Validator<E> forType(final Class<E> source) {
100            if (null == lexer) {
101                lexer = useSimpleElWithSquaredBrackets(source);
102            }
103            return new Validator<>(lexer);
104        }
105
106        public Validator<E> withLexer(final Lexer<E> lexerInstance) {
107            return new Validator<>(lexerInstance);
108        }
109
110        public Validator<E> forSource(E source) {
111            if (null == lexer) {
112                lexer = useSimpleElWithSquaredBrackets(source);
113            }
114            return new Validator<>(lexer);
115        }
116
117        private Lexer<E> useSimpleElWithSquaredBrackets(final Class<E> source) {
118            return LexerBuilder.useSimpleElWithSquaredBrackets().build(source);
119        }
120
121        private Lexer<E> useSimpleElWithSquaredBrackets(E source) {
122            return LexerBuilder.useSimpleElWithSquaredBrackets().build(source);
123        }
124
125    }
126}