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.test.valueobjects.util; 017 018import static java.util.Objects.requireNonNull; 019 020import java.util.Arrays; 021import java.util.Collection; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025import java.util.Set; 026 027import de.cuioss.test.valueobjects.api.property.PropertyBuilderConfig; 028import de.cuioss.test.valueobjects.api.property.PropertyBuilderConfigs; 029import de.cuioss.test.valueobjects.property.PropertyMetadata; 030import de.cuioss.test.valueobjects.property.impl.BuilderMetadata; 031import de.cuioss.test.valueobjects.property.impl.PropertyMetadataImpl; 032import de.cuioss.tools.collect.CollectionBuilder; 033import de.cuioss.tools.reflect.MoreReflection; 034import lombok.experimental.UtilityClass; 035 036/** 037 * Utility class for dealing with and the {@link PropertyBuilderConfig} and 038 * {@link PropertyBuilderConfigs} annotations. 039 * 040 * @author Oliver Wolff 041 */ 042@UtilityClass 043public final class BuilderPropertyHelper { 044 045 /** 046 * Checks the given type for the annotation {@link PropertyBuilderConfig} and 047 * {@link PropertyBuilderConfigs} and puts all found in the immutable 048 * {@link List} to be returned 049 * 050 * @param annotated the class that may or may not provide the annotations, 051 * must not be null 052 * @param givenMetadata must not be null 053 * @return immutable {@link List} of found {@link PropertyMetadata} elements 054 * derived by the annotations. 055 */ 056 public static List<PropertyMetadata> handleBuilderPropertyConfigAnnotations(final Class<?> annotated, 057 final List<PropertyMetadata> givenMetadata) { 058 requireNonNull(annotated); 059 final var builder = new CollectionBuilder<PropertyMetadata>(); 060 061 extractConfiguredPropertyBuilderConfigs(annotated) 062 .forEach(config -> builder.add(builderPropertyConfigToBuilderMetadata(config, givenMetadata))); 063 064 return builder.toImmutableList(); 065 } 066 067 /** 068 * Checks the given type for the annotation {@link PropertyBuilderConfig} and 069 * {@link PropertyBuilderConfigs} and puts all found in the immutable 070 * {@link Set} to be returned 071 * 072 * @param annotated the class that may or may not provide the annotations, must 073 * not be null 074 * @return immutable {@link Set} of found {@link PropertyBuilderConfig} 075 * elements. 076 */ 077 public static Set<PropertyBuilderConfig> extractConfiguredPropertyBuilderConfigs(final Class<?> annotated) { 078 requireNonNull(annotated); 079 final var builder = new CollectionBuilder<PropertyBuilderConfig>(); 080 081 MoreReflection.extractAllAnnotations(annotated, PropertyBuilderConfigs.class) 082 .forEach(contract -> builder.add(Arrays.asList(contract.value()))); 083 MoreReflection.extractAllAnnotations(annotated, PropertyBuilderConfig.class).forEach(builder::add); 084 085 return builder.toImmutableSet(); 086 } 087 088 private static PropertyMetadata builderPropertyConfigToBuilderMetadata(final PropertyBuilderConfig config, 089 final Collection<PropertyMetadata> givenMetadata) { 090 091 final Map<String, PropertyMetadata> map = new HashMap<>(); 092 givenMetadata.forEach(meta -> map.put(meta.getName(), meta)); 093 PropertyHelper.assertPropertyExists(config.name(), map); 094 095 final var metatada = PropertyMetadataImpl.builder(map.get(config.name())) 096 .propertyAccessStrategy(config.propertyAccessStrategy()).build(); 097 098 return BuilderMetadata.builder().delegateMetadata(metatada).builderMethodName(config.builderMethodName()) 099 .builderMethodPrefix(config.methodPrefix()) 100 .builderSingleAddMethodName(config.builderSingleAddMethodName()).build(); 101 } 102 103}