package de.banananetwork.dsa.requirements; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.function.Supplier; public abstract class Requirement { public abstract RequirementCheckResult checkOn(Character character); private static class SingleRequirement extends Requirement { } private static class CombinedRequirement extends Requirement { private final RequirementLink requirementLink; private final Requirement[] requirements; private CombinedRequirement(RequirementLink requirementLink, Requirement[] requirements) { this.requirementLink = requirementLink; this.requirements = requirements; } @Override public RequirementCheckResult checkOn(Character character) { return null; } } public static class Builder { private final List> requirements = new ArrayList<>(); private RequirementLink requirementLink; public Builder(RequirementLink requirementLink) { this.requirementLink = requirementLink; } Builder add(Supplier requirementSupplier) { this.requirements.add(requirementSupplier); return this; } public Builder add(Requirement requirement) { return this.add(() -> requirement); } public Builder add(Builder requirement) { return this.add(requirement::create); } private Builder addAll(Collection> requirements) { this.requirements.addAll(requirements); return this; } public Builder addAll(Builder requirements) { return this.addAll(requirements.requirements); } private Requirement create() { switch (this.requirements.size()) { case 0: throw new IllegalStateException(); case 1: return this.requirements.get(0).get(); default: return new CombinedRequirement(this.requirementLink, this.requirements.stream().map(Supplier::get).toArray(Requirement[]::new)); } } } }