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 de.cuioss.tools.collect.CollectionLiterals.immutableSet;
019import static java.util.Objects.requireNonNull;
020
021import java.util.Arrays;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Set;
025
026import de.cuioss.test.valueobjects.api.object.ObjectTestContracts;
027import de.cuioss.test.valueobjects.api.object.VerifyObjectTestContract;
028import de.cuioss.test.valueobjects.api.object.VetoObjectTestContract;
029import de.cuioss.test.valueobjects.api.object.VetoObjectTestContracts;
030import de.cuioss.tools.collect.CollectionBuilder;
031import de.cuioss.tools.reflect.MoreReflection;
032import lombok.experimental.UtilityClass;
033
034/**
035 * Utility class for dealing with {@link ObjectTestContracts} and the
036 * {@link VetoObjectTestContract} and {@link VetoObjectTestContracts}
037 * annotations.
038 *
039 * @author Oliver Wolff
040 */
041@UtilityClass
042public final class ObjectContractHelper {
043
044    /**
045     * Checks the given type for the annotation {@link VetoObjectTestContract} and
046     * {@link VetoObjectTestContracts} creates a set with all
047     * {@link ObjectTestContracts#OBJECT_CONTRACTS} but the vetoed contracts.
048     *
049     * @param annotated the class that may or may not provide the annotations, must
050     *                  not be null
051     * @return immutable set of found {@link ObjectTestContracts} elements.
052     */
053    public static Set<ObjectTestContracts> handleVetoedContracts(final Class<?> annotated) {
054        final Set<ObjectTestContracts> objectTestContracts = new HashSet<>(ObjectTestContracts.OBJECT_CONTRACTS);
055
056        extractConfiguredVetoObjectContracts(annotated)
057                .forEach(veto -> objectTestContracts.removeAll(Arrays.asList(veto.value())));
058
059        return immutableSet(objectTestContracts);
060    }
061
062    /**
063     * Checks the given type for the annotation {@link VetoObjectTestContract} and
064     * {@link VetoObjectTestContracts} and puts all found in the immutable list to
065     * be returned
066     *
067     * @param annotated the class that may or may not provide the annotations, must
068     *                  not be null
069     * @return immutable {@link Set} of found {@link VetoObjectTestContract}
070     *         elements.
071     */
072    public static Set<VetoObjectTestContract> extractConfiguredVetoObjectContracts(final Class<?> annotated) {
073        requireNonNull(annotated);
074        final var builder = new CollectionBuilder<VetoObjectTestContract>();
075
076        MoreReflection.extractAllAnnotations(annotated, VetoObjectTestContracts.class)
077                .forEach(contract -> builder.add(contract.value()));
078        MoreReflection.extractAllAnnotations(annotated, VetoObjectTestContract.class).forEach(builder::add);
079
080        return builder.toImmutableSet();
081    }
082
083    /**
084     * Checks the given type for the annotation {@link VerifyObjectTestContract} and
085     * creates a set with all corresponding {@link ObjectTestContracts}.
086     *
087     * @param annotated the class that may or may not provide the annotations, must
088     *                  not be null
089     * @return immutable set of found {@link ObjectTestContracts} elements.
090     */
091    public static Set<ObjectTestContracts> handleOptedInContracts(final Class<?> annotated) {
092        final Set<ObjectTestContracts> builder = new HashSet<>();
093
094        List<VerifyObjectTestContract> annotations = MoreReflection.extractAllAnnotations(annotated,
095                VerifyObjectTestContract.class);
096        if (!annotations.isEmpty()) {
097            builder.addAll(Arrays.asList(ObjectTestContracts.values()));
098        }
099        annotations.forEach(a -> builder.removeAll(Arrays.asList(a.veto())));
100        return immutableSet(builder);
101    }
102
103}