All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.vergne.pester.definition.PropertyDefinition Maven / Gradle / Ivy

The newest version!
package fr.vergne.pester.definition;

import static java.util.function.Predicate.*;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import fr.vergne.pester.options.Mutability;
import fr.vergne.pester.options.Option;
import fr.vergne.pester.options.Scope;
import fr.vergne.pester.options.Visibility;
import fr.vergne.pester.util.namer.NameNamer;
import fr.vergne.pester.util.namer.Namer;
import fr.vergne.pester.util.namer.PredicateNamer;
import fr.vergne.pester.value.Generator;
import fr.vergne.pester.value.Modifier;
import fr.vergne.pester.value.Nullable;
import fr.vergne.pester.value.Type;

public class PropertyDefinition {

	private final Class

pojoClass; private final String name; private final Type type; private Optional> fieldDefinition = Optional.empty(); private Optional> getterDefinition = Optional.empty(); private Optional> setterDefinition = Optional.empty(); private Optional> modifier = Optional.empty(); private Optional> generator = Optional.empty(); private Optional> defaultValue = Optional.empty(); public PropertyDefinition(Class

pojoClass, String name, Type type) { this.pojoClass = pojoClass; this.name = name; this.type = type; } // BASE public String getName() { return name; } public Type getType() { return type; } // FIELD public PropertyDefinition withField(Option... options) { return withField(name, options); } public PropertyDefinition withField(String name, Option... options) { return withFieldInternal(name, extractOption(options, Mutability.class), extractOption(options, Visibility.class), extractOption(options, Scope.class)); } private static Optional extractOption(Option[] options, Class optionType) { List providedOptions = Stream.of(options) .distinct() .filter(optionType::isInstance) .map(optionType::cast) .collect(Collectors.toList()); if (providedOptions.size() > 1) { throw new IllegalArgumentException(String.format("More than one %s provided: %s", optionType.getSimpleName(), providedOptions)); } else { return providedOptions.stream().findFirst(); } } private PropertyDefinition withFieldInternal(String name, Optional mutability, Optional visibility, Optional scope) { this.fieldDefinition = Optional.of(new FieldDefinition<>(pojoClass, name, visibility, mutability, scope)); return this; } public Optional> getFieldDefinition() { return fieldDefinition; } // GETTER private final Predicate isBooleanClass = isEqual(boolean.class).or(isEqual(Boolean.class)); public PropertyDefinition withGetter(Option... options) { List possibleNames = new LinkedList(); possibleNames.add(name); possibleNames.add("get"+capitalize(name)); if (type.getTypeClass().filter(isBooleanClass).isPresent()) { possibleNames.add("is" + capitalize(name)); } Namer namer = new PredicateNamer("getter for " + name, createPatternForNames(possibleNames).asPredicate()); return withGetter(namer, options); } public PropertyDefinition withGetter(String name, Option... options) { return withGetter(new NameNamer(name), options); } private PropertyDefinition withGetter(Namer namer, Option... options) { return withGetter(namer, extractOption(options, Mutability.class), extractOption(options, Visibility.class), extractOption(options, Scope.class)); } private PropertyDefinition withGetter(Namer namer, Optional mutability, Optional visibility, Optional scope) { this.getterDefinition = Optional.of(new GetterDefinition(pojoClass, namer, visibility, mutability, scope)); return this; } public Optional> getGetterDefinition() { return getterDefinition; } // SETTER public PropertyDefinition withSetter(Option... options) { List possibleNames = Arrays.asList(name, "set" + capitalize(name), "with" + capitalize(name)); Namer namer = new PredicateNamer("setter for " + name, createPatternForNames(possibleNames).asPredicate()); return withSetter(namer, options); } public PropertyDefinition withSetter(String name, Option... options) { return withSetter(new NameNamer(name), options); } private PropertyDefinition withSetter(Namer namer, Option... options) { return withSetter(namer, extractOption(options, Mutability.class), extractOption(options, Visibility.class), extractOption(options, Scope.class)); } private PropertyDefinition withSetter(Namer namer, Optional mutability, Optional visibility, Optional scope) { this.setterDefinition = Optional.of(new SetterDefinition<>(pojoClass, type, namer, visibility, mutability, scope)); return this; } public Optional> getSetterDefinition() { return setterDefinition; } // DEFAULT VALUE public PropertyDefinition withDefaultValue(T value) { this.defaultValue = Optional.of(Nullable.of(value)); return this; } public Optional> getDefaultValue() { return defaultValue; } // GENERATOR public PropertyDefinition withGenerator(Generator generator) { this.generator = Optional.of(generator); return this; } public Generator getGenerator() { return generator.orElse(type.getGenerator()); } // MODIFIER public PropertyDefinition withModifier(Modifier modifier) { this.modifier = Optional.of(modifier); return this; } public Modifier getModifier() { return modifier.orElse(type.getModifier()); } // MISCELLANEOUS private String capitalize(String name) { return name.substring(0, 1).toUpperCase() + name.substring(1); } private Pattern createPatternForNames(List names) { return Pattern.compile( names.stream() .map(Pattern::quote) .collect(Collectors.joining("|", "^", "$"))); } }