001// Generated by delombok at Sun Jul 30 17:21:56 UTC 2023
002package de.cuioss.test.jsf.component;
003
004import static java.util.Objects.requireNonNull;
005import java.util.ArrayList;
006import java.util.Arrays;
007import java.util.Collections;
008import java.util.HashMap;
009import java.util.List;
010import java.util.Map;
011import java.util.Map.Entry;
012import javax.faces.component.UIComponent;
013import de.cuioss.test.jsf.config.component.VerifyComponentProperties;
014import de.cuioss.test.valueobjects.generator.dynamic.GeneratorResolver;
015import de.cuioss.test.valueobjects.property.PropertyMetadata;
016import de.cuioss.test.valueobjects.property.impl.PropertyMetadataImpl;
017import de.cuioss.test.valueobjects.property.util.CollectionType;
018import de.cuioss.test.valueobjects.util.AnnotationHelper;
019import de.cuioss.test.valueobjects.util.PropertyHelper;
020import de.cuioss.tools.property.PropertyHolder;
021import de.cuioss.tools.property.PropertyReadWrite;
022import de.cuioss.tools.reflect.MoreReflection;
023
024/**
025 * Helper class providing utility methods for convenient filtering of
026 * properties.
027 *
028 * @author Oliver Wolff
029 */
030public final class ComponentTestHelper {
031    /**
032     * Filters the given metadata according to the annotations
033     * {@link VerifyComponentProperties} found on the given annotated type
034     *
035     * @param annotated must not be null
036     * @param instance  of the type to be checked.
037     * @return the filtered list with {@link ComponentPropertyMetadata}
038     */
039    public static List<ComponentPropertyMetadata> filterPropertyMetadata(final Class<?> annotated, final UIComponent instance) {
040        requireNonNull(annotated);
041        requireNonNull(instance);
042        var propertyConfigs = PropertyHelper.handlePropertyConfigAnnotations(annotated);
043        var of = new ArrayList<String>();
044        var defaultValued = new ArrayList<String>();
045        var noVE = new ArrayList<String>();
046        var unorderedCollection = new ArrayList<String>();
047        for (VerifyComponentProperties property : MoreReflection.extractAllAnnotations(annotated, VerifyComponentProperties.class)) {
048            of.addAll(Arrays.asList(property.of()));
049            defaultValued.addAll(Arrays.asList(property.defaultValued()));
050            noVE.addAll(Arrays.asList(property.noValueExpression()));
051            unorderedCollection.addAll(Arrays.asList(property.assertUnorderedCollection()));
052        }
053        final Map<String, PropertyMetadata> map = new HashMap<>();
054        propertyConfigs.forEach(pc -> map.put(pc.getName(), pc));
055        for (String configuredName : of) {
056            map.put(configuredName, resolvePropertyForConfiguredName(instance, configuredName));
057        }
058        var filtered = AnnotationHelper.modifyPropertyMetadata(map, defaultValued, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), unorderedCollection);
059        List<ComponentPropertyMetadata> found = new ArrayList<>();
060        for (Entry<String, PropertyMetadata> entry : filtered.entrySet()) {
061            found.add(new ComponentPropertyMetadata(entry.getValue(), noVE.contains(entry.getKey())));
062        }
063        return found;
064    }
065
066    /**
067     * Creates a {@link PropertyMetadata} for the given propertyName on the given
068     * type.
069     *
070     * @param instance       must not be null
071     * @param configuredName must not be null
072     * @return {@link PropertyMetadata} instance with the corresponding attributes.
073     */
074    public static PropertyMetadata resolvePropertyForConfiguredName(final UIComponent instance, final String configuredName) {
075        Class<?> propertyType = null;
076        var collectionType = CollectionType.NO_ITERABLE;
077        propertyType = PropertyHolder.from(instance.getClass(), configuredName).orElseThrow(() -> new IllegalStateException("Unable to determine property type for " + configuredName + ", use @PropertyConfig to define this property")).getType();
078        final var collectionTypeOption = CollectionType.findResponsibleCollectionType(propertyType);
079        if (collectionTypeOption.isPresent()) {
080            throw new IllegalStateException(String.format("Unable to determine generic-type for %s, you need to " + "provide a custom @PropertyConfig for this field", configuredName));
081        }
082        return PropertyMetadataImpl.builder().propertyClass(propertyType).name(configuredName).collectionType(collectionType).defaultValue(propertyType.isPrimitive()).generator(GeneratorResolver.resolveGenerator(propertyType)).propertyReadWrite(PropertyReadWrite.READ_WRITE).build();
083    }
084
085    @java.lang.SuppressWarnings("all")
086    @lombok.Generated
087    private ComponentTestHelper() {
088        throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
089    }
090}