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.property;
017
018import java.io.Serializable;
019
020import de.cuioss.test.generator.TypedGenerator;
021import de.cuioss.test.generator.impl.CollectionGenerator;
022import de.cuioss.test.valueobjects.property.util.AssertionStrategy;
023import de.cuioss.test.valueobjects.property.util.CollectionType;
024import de.cuioss.test.valueobjects.property.util.PropertyAccessStrategy;
025import de.cuioss.tools.property.PropertyMemberInfo;
026import de.cuioss.tools.property.PropertyReadWrite;
027
028/**
029 * Represents runtime information for a certain property. This contains all
030 * metadata that may be needed.
031 *
032 * @author Oliver Wolff
033 */
034public interface PropertyMetadata extends Comparable<PropertyMetadata> {
035
036    /**
037     * Identifies the name of the property
038     *
039     * @return the actual name of the property, must never be null nor empty
040     */
041    String getName();
042
043    /**
044     * @return the type of the property. This can either be the actual type, in case
045     *         {@link #getCollectionType()} is {@link CollectionType#NO_ITERABLE},
046     *         the component-type in case of {@link CollectionType#ARRAY_MARKER} or
047     *         the type argument for a collection for the other
048     *         {@link CollectionType}s, see {@link #next()} and
049     *         {@link #resolveActualClass()}
050     */
051    Class<?> getPropertyClass();
052
053    /**
054     * Generates a next random value Similar to {@link TypedGenerator#next()} but in
055     * case there is a {@link #getCollectionType()} that is not
056     * {@link CollectionType#NO_ITERABLE} it wraps the content of the contained
057     * generator into a the corresponding collectionWrapper, see
058     * {@link CollectionType#nextIterable(CollectionGenerator)}
059     *
060     * @return the next generated value
061     */
062    Object next();
063
064    /**
065     * @return The actual class of the property. PropertyMetadata can always be used
066     *         directly or the data can be implicitly wrapped into a collection or
067     *         an array. This method computes the actual class of the property
068     *         combining both informations
069     */
070    Class<?> resolveActualClass();
071
072    /**
073     * @return a new instance of {@link CollectionGenerator} wrapping the contained
074     *         generator;
075     */
076    @SuppressWarnings("squid:S1452") // owolff: No type information available at this level,
077                                     // therefore the wildcard is needed
078    CollectionGenerator<?> resolveCollectionGenerator();
079
080    /**
081     * @return the wrapped {@link TypedGenerator} to dynamically create properties.
082     */
083    @SuppressWarnings("squid:S1452") // owolff: No type information available at this level,
084                                     // therefore the wildcard is needed
085    TypedGenerator<?> getGenerator();
086
087    /**
088     * @return boolean indicating whether the attribute defines a default-value.
089     *         Default is false.
090     */
091    boolean isDefaultValue();
092
093    /**
094     * Indicates that the attribute is required.
095     *
096     * @return boolean indicating whether the attribute is required, defaults to
097     *         false.
098     */
099    boolean isRequired();
100
101    /**
102     * Defines the way properties are to be written / read
103     *
104     * @return the {@link PropertyAccessStrategy}, must never be null, defaults to
105     *         {@link PropertyAccessStrategy#BEAN_PROPERTY}
106     */
107    PropertyAccessStrategy getPropertyAccessStrategy();
108
109    /**
110     * In case there is a collectionWrapper defined the generated values will
111     * implicitly wrapped in the corresponding collection class defined by that
112     * wrapper.
113     *
114     * @return the {@link CollectionType} represented by this
115     *         {@link PropertyMetadata}. Must never be null but may be
116     *         {@link CollectionType#NO_ITERABLE}
117     */
118    CollectionType getCollectionType();
119
120    /**
121     * Indicates the way the corresponding property is subject to the contracts
122     * regarding the canonical Object methods like {@link Object#equals(Object)},
123     * {@link Object#hashCode()} and {@link Object#toString()} and the
124     * {@link Serializable} contract. The default is
125     * {@link PropertyMemberInfo#DEFAULT}
126     *
127     * @return the {@link PropertyMemberInfo}, must never be null
128     */
129    PropertyMemberInfo getPropertyMemberInfo();
130
131    /**
132     * @return {@link PropertyReadWrite} indicating whether a property can be read
133     *         or written too, defaults to {@link PropertyReadWrite#READ_WRITE}
134     */
135    PropertyReadWrite getPropertyReadWrite();
136
137    /**
138     * Defines the the way how to deal with equality regarding
139     * PropertySupport.assertValueSet(Object)
140     *
141     * @return the {@link AssertionStrategy}, defaults to
142     *         {@link AssertionStrategy#DEFAULT}
143     */
144    AssertionStrategy getAssertionStrategy();
145
146}