com.teradata.tempto.Requirements.java Source code

Java tutorial

Introduction

Here is the source code for com.teradata.tempto.Requirements.java

Source

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.teradata.tempto;

import com.google.common.collect.ImmutableSet;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import static com.google.common.collect.ImmutableSet.copyOf;
import static com.google.common.collect.Lists.transform;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Arrays.asList;

/**
 * An utility class for composing requirements.
 */
public final class Requirements {
    public static CompositeRequirement compose(Requirement... requirements) {
        return compose(asList(requirements));
    }

    public static CompositeRequirement compose(List<Requirement> requirements) {
        return new MultiCompositeRequirement(ImmutableSet.of(copyOf(wrapAsCompositeRequirements(requirements))));
    }

    public static CompositeRequirement allOf(Requirement... requirements) {
        return allOf(asList(requirements));
    }

    public static CompositeRequirement allOf(List<Requirement> requirements) {
        return new MultiCompositeRequirement(copyOf(
                transform(wrapAsCompositeRequirements(requirements), ImmutableSet::<CompositeRequirement>of)));
    }

    private static List<CompositeRequirement> wrapAsCompositeRequirements(List<Requirement> requirements) {
        return transform(requirements, (Requirement requirement) -> {
            if (requirement instanceof CompositeRequirement) {
                return (CompositeRequirement) requirement;
            } else {
                return new SingletonCompositeRequirement(requirement);
            }
        });
    }

    private static class SingletonCompositeRequirement implements CompositeRequirement {

        private final Set<Set<Requirement>> requirementsSets;

        public SingletonCompositeRequirement(Requirement requirement) {
            this.requirementsSets = ImmutableSet.of(ImmutableSet.of(requirement));
        }

        public Set<Set<Requirement>> getRequirementsSets() {
            return requirementsSets;
        }
    }

    private static class MultiCompositeRequirement implements CompositeRequirement {

        private final Set<Set<CompositeRequirement>> requirementsSetsBranches;

        public MultiCompositeRequirement(Set<Set<CompositeRequirement>> requirementsSetsBranches) {
            this.requirementsSetsBranches = requirementsSetsBranches;
        }

        @Override
        public Set<Set<Requirement>> getRequirementsSets() {
            Set<Set<Requirement>> expandedRequirementsSets = newHashSet();
            for (Set<CompositeRequirement> requirementsSetsBranch : requirementsSetsBranches) {
                expandedRequirementsSets.addAll(expandRequirements(requirementsSetsBranch));
            }
            return expandedRequirementsSets;
        }

        private Set<Set<Requirement>> expandRequirements(Collection<CompositeRequirement> requirementsSetsBranch) {
            Set<Set<Requirement>> expandedRequirementsSets = ImmutableSet.of(ImmutableSet.of());
            for (CompositeRequirement requirementsSets : requirementsSetsBranch) {
                expandedRequirementsSets = expandRequirements(expandedRequirementsSets, requirementsSets);
            }
            return expandedRequirementsSets;
        }

        private Set<Set<Requirement>> expandRequirements(Set<Set<Requirement>> expandedRequirementsSets,
                CompositeRequirement requirementsSets) {
            Set<Set<Requirement>> newExpandedRequirementsSets = newHashSet();
            for (Set<Requirement> expandedRequirementSet : expandedRequirementsSets) {
                for (Set<Requirement> requirementSet : requirementsSets.getRequirementsSets()) {
                    Set<Requirement> newExpandedRequirementSet = ImmutableSet.<Requirement>builder()
                            .addAll(expandedRequirementSet).addAll(requirementSet).build();
                    newExpandedRequirementsSets.add(newExpandedRequirementSet);
                }
            }
            return newExpandedRequirementsSets;
        }
    }

    private Requirements() {
    }
}