001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2024–2025 microBean™. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 011 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 012 * specific language governing permissions and limitations under the License. 013 */ 014package org.microbean.bean; 015 016import java.util.Collection; 017import java.util.Collections; 018import java.util.SequencedSet; 019 020import java.util.function.Function; 021 022import static java.util.Collections.unmodifiableSequencedSet; 023 024import static java.util.LinkedHashSet.newLinkedHashSet; 025 026/** 027 * An object with {@linkplain AttributedElement dependencies}. 028 * 029 * <p>By default, {@link Aggregate}s have {@linkplain #EMPTY_DEPENDENCIES no dependencies}.</p> 030 * 031 * @author <a href="https://about.me/lairdnelson/" target="_top">Laird Nelson</a> 032 * 033 * @see #dependencies() 034 */ 035public interface Aggregate { 036 037 038 /* 039 * Static fields. 040 */ 041 042 043 /** 044 * An immutable, empty {@link SequencedSet} of {@link Assignment}s. 045 */ 046 public static final SequencedSet<Assignment<?>> EMPTY_ASSIGNMENTS = unmodifiableSequencedSet(newLinkedHashSet(0)); 047 048 /** 049 * An immutable, empty {@link SequencedSet} of {@link AttributedElement}s. 050 */ 051 public static final SequencedSet<AttributedElement> EMPTY_DEPENDENCIES = unmodifiableSequencedSet(newLinkedHashSet(0)); 052 053 054 /* 055 * Default instance methods. 056 */ 057 058 059 /** 060 * Returns an immutable {@link SequencedSet} of {@link AttributedElement} instances. 061 * 062 * @return an immutable {@link SequencedSet} of {@link AttributedElement} instances; never {@code null} 063 * 064 * @see AttributedElement 065 */ 066 public default SequencedSet<AttributedElement> dependencies() { 067 return EMPTY_DEPENDENCIES; 068 } 069 070 /** 071 * A convenience method that assigns a contextual reference to each of this {@link Aggregate}'s {@link 072 * AttributedElement} instances and returns the resulting {@link SequencedSet} of {@link Assignment}s. 073 * 074 * <p>Typically there is no need to override this method.</p> 075 * 076 * @param r a {@link Function} that retrieves a contextual reference suitable for an {@link AttributedType}; if {@link 077 * #dependencies()} returns a non-empty {@link SequencedSet} then this argument must not be {@code null}; normally a 078 * reference to the {@link Request#reference(AttributedType)} method 079 * 080 * @return an immutable {@link SequencedSet} of {@link Assignment} instances; never {@code null} 081 * 082 * @exception NullPointerException if {@code r} is {@code null} 083 */ 084 public default SequencedSet<? extends Assignment<?>> assign(final Function<? super AttributedType, ?> r) { 085 final Collection<? extends AttributedElement> ds = this.dependencies(); 086 if (ds == null || ds.isEmpty()) { 087 return EMPTY_ASSIGNMENTS; 088 } 089 final SequencedSet<Assignment<?>> assignments = newLinkedHashSet(ds.size()); 090 ds.forEach(d -> assignments.add(new Assignment<>(d, r.apply(d.attributedType())))); 091 return Collections.unmodifiableSequencedSet(assignments); 092 } 093 094}