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.lexer; 017 018import static java.util.Objects.requireNonNull; 019 020import java.lang.reflect.InvocationTargetException; 021import java.util.EnumSet; 022 023import de.cuioss.tools.formatting.template.FormatterSupport; 024import de.cuioss.tools.formatting.template.lexer.BracketLexer.Brackets; 025import de.cuioss.tools.formatting.template.lexer.Lexer.ExpressionLanguage; 026import lombok.AccessLevel; 027import lombok.NoArgsConstructor; 028 029/** 030 * @author Eugen Fischer 031 */ 032@NoArgsConstructor(access = AccessLevel.PRIVATE) 033public final class LexerBuilder { 034 035 static final EnumSet<ExpressionLanguage> SIMPLE = EnumSet.of(ExpressionLanguage.SIMPLE_SQUARED_BRACKTES, 036 ExpressionLanguage.SIMPLE_CURLY_BRACKETS, ExpressionLanguage.SIMPLE_ANGLE_BRACKET); 037 038 /** 039 * @return the builder with {@link ExpressionLanguage#SIMPLE_SQUARED_BRACKTES} 040 */ 041 public static Builder useSimpleElWithSquaredBrackets() { 042 return new Builder(ExpressionLanguage.SIMPLE_SQUARED_BRACKTES); 043 } 044 045 /** 046 * @param expLanguage {@link ExpressionLanguage} must not be null 047 * 048 * @return builder with the given {@link ExpressionLanguage} 049 */ 050 public static Builder withExpressionLanguage(final ExpressionLanguage expLanguage) { 051 requireNonNull(expLanguage, "ExpressionLanguage must not be null."); 052 return new Builder(expLanguage); 053 } 054 055 /** 056 * The builder class 057 */ 058 public static final class Builder { 059 060 private final ExpressionLanguage expl; 061 062 private boolean strict = false; 063 064 private Builder(final ExpressionLanguage expLanguage) { 065 expl = expLanguage; 066 } 067 068 private static Brackets getBracketsTypeFor(final ExpressionLanguage expl) { 069 return switch (expl) { 070 case SIMPLE_SQUARED_BRACKTES -> Brackets.SQUARED_BRACKETS; 071 case SIMPLE_CURLY_BRACKETS -> Brackets.CURLY_BRACKETS; 072 case SIMPLE_ANGLE_BRACKET -> Brackets.ANGLE_BRACKET; 073 default -> throw new IllegalArgumentException(expl + " doesn't belongs to Simple expression language."); 074 }; 075 } 076 077 /** 078 * @param strict enabling the strict mode for pattern matching (only match exact 079 * name) instead of best fitting 080 * @return The concrete {@link Builder} 081 */ 082 public Builder strict(boolean strict) { 083 this.strict = strict; 084 return this; 085 } 086 087 /** 088 * Build the formatter for {@link FormatterSupport} type 089 * 090 * @param source {@link FormatterSupport} type 091 * 092 * @return created formatter 093 */ 094 public <F extends FormatterSupport> Lexer<F> build(final F source) { 095 if (SIMPLE.contains(expl)) { 096 return new BracketLexer<>(source, getBracketsTypeFor(expl), strict); 097 } 098 throw new IllegalArgumentException(expl + " doesn't belongs to Simple expression language."); 099 } 100 101 /** 102 * @param sourceType bean type 103 * 104 * @return Lexer for classType 105 * @throws IllegalStateException if access to the class constructor fails or 106 * class isn't public 107 */ 108 public <F extends FormatterSupport> Lexer<F> build(final Class<F> sourceType) { 109 try { 110 return build(sourceType.getDeclaredConstructor().newInstance()); 111 } catch (final RuntimeException | InstantiationException | IllegalAccessException 112 | InvocationTargetException | NoSuchMethodException e) { 113 throw new IllegalStateException( 114 "Class '" + sourceType + "' should provide an accessible default constructor.", e); 115 } 116 } 117 118 } 119 120}