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.objects.impl; 017 018import static java.util.Objects.requireNonNull; 019 020import java.util.ArrayList; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import de.cuioss.test.valueobjects.objects.ParameterizedInstantiator; 026import de.cuioss.test.valueobjects.objects.RuntimeProperties; 027import de.cuioss.test.valueobjects.property.PropertyMetadata; 028import de.cuioss.test.valueobjects.property.PropertySupport; 029import lombok.Getter; 030 031/** 032 * Base class for creating objects with a fixed set of parameter to be used. 033 * This can be constructor and or factory based 034 * {@link ParameterizedInstantiator}. 035 * 036 * @author Oliver Wolff 037 * @param <T> 038 */ 039public abstract class AbstractOrderedArgsInstantiator<T> implements ParameterizedInstantiator<T> { 040 041 @Getter 042 private final RuntimeProperties runtimeProperties; 043 044 /** 045 * Constructor. 046 * 047 * @param runtimeProperties must not be null. defines the attributes in the 048 * exact order to be used for the constructor: 049 * {@link RuntimeProperties#getAllProperties()} 050 */ 051 protected AbstractOrderedArgsInstantiator(final RuntimeProperties runtimeProperties) { 052 requireNonNull(runtimeProperties); 053 054 this.runtimeProperties = runtimeProperties; 055 } 056 057 /** 058 * Wraps the given {@link Class} elements to a corresponding array 059 * 060 * @param parameter may be null 061 * @return the array 062 */ 063 static Class<?>[] toClassArray(final List<Class<?>> parameter) { 064 if (null == parameter || parameter.isEmpty()) { 065 return new Class<?>[0]; 066 } 067 final var parameterArray = new Class<?>[parameter.size()]; 068 for (var i = 0; i < parameterArray.length; i++) { 069 parameterArray[i] = parameter.get(i); 070 } 071 return parameterArray; 072 } 073 074 @Override 075 public T newInstance(final List<PropertySupport> properties, final boolean generatePropertyValues) { 076 final Map<String, PropertySupport> given = new HashMap<>(); 077 properties.forEach(p -> given.put(p.getName(), p)); 078 final List<Object> parameter = new ArrayList<>(); 079 for (final PropertySupport support : resolveFixedArgumentList()) { 080 if (given.containsKey(support.getName())) { 081 // Use given element 082 final var givenSupport = given.get(support.getName()); 083 if (generatePropertyValues) { 084 givenSupport.generateTestValue(); 085 } 086 parameter.add(givenSupport.getGeneratedValue()); 087 } else { 088 if (null != support.getGeneratedValue()) { 089 // A Test value is already set 090 } else if (support.isRequired() || support.isPrimitive()) { 091 support.generateTestValue(); 092 } 093 parameter.add(support.getGeneratedValue()); 094 } 095 } 096 return doInstantiate(parameter.toArray()); 097 } 098 099 /** 100 * The actual instantiation method for the {@link Object}s 101 * 102 * @param args Object[] of parameter to be passed to Constructor / factory , 103 * method 104 * @return the instantiated {@link Object} 105 */ 106 protected abstract T doInstantiate(Object... args); 107 108 @Override 109 public T newInstance(final List<PropertyMetadata> properties) { 110 return newInstance(RuntimeProperties.mapToPropertySupport(properties, false), true); 111 } 112 113 @Override 114 public T newInstanceMinimal() { 115 return newInstance(getRuntimeProperties().getRequiredAsPropertySupport(false), true); 116 } 117 118 @Override 119 public T newInstanceFull() { 120 return newInstance(resolveFixedArgumentList(), true); 121 } 122 123 protected List<PropertySupport> resolveFixedArgumentList() { 124 return getRuntimeProperties().getAllAsPropertySupport(false); 125 } 126 127}