001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2024 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
016/**
017 * A request for a contextual reference of a particular type, along with functionality to help fulfil the request.
018 *
019 * @param <I> the type of the contextual reference
020 *
021 * @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a>
022 *
023 * @see #beanReduction()
024 *
025 * @see ReferenceSelector
026 *
027 * @see Creation
028 */
029public interface Request<I> extends Creation<I>, ReferenceSelector {
030
031  /**
032   * Returns the {@link BeanReduction} describing this {@link Request} in progress.
033   *
034   * @return the {@link BeanReduction} describing this {@link Request} in progress; never {@code null}
035   *
036   * @idempotency Implementations of this method must be idempotent and deterministic.
037   *
038   * @nullability Implementations of this method must not return {@code null}.
039   *
040   * @threadsafety Implementations of this method must be safe for concurrent use by multiple threads.
041   *
042   * @see BeanReduction
043   */
044  public BeanReduction<I> beanReduction();
045
046  // Returns a "child" Request, where "childness" means "in the service of the parent". So a request for a
047  // CoffeeMaker is the logical parent of a request for a Heater, which is the new child.
048  //
049  // If the supplied BeanReduction is equal to this Request's current beanReduction(), it is permissible for this
050  // Request to be returned instead.
051  //
052  // It is very common for a Request implementation to also be (or house) an AutoCloseableRegistry implementation. So if
053  // the Heater object is in "none"/dependent scope, it should get added to the CoffeeMaker parent's set of
054  // AutoCloseables to be closed when the parent goes out of scope, and if a child request for a Fuse object gets
055  // created, then the Fuse should be added to the Heater child's set of AutoCloseables, and so on.
056  //
057  // See AutoCloseableRegistry#newChild() for how that part works.
058  //
059  // Note that the semantics of this newChild(BeanReduction) method don't have the same "tree node"-like quality as
060  // AutoCloseableRegistry#newChild(). That is, there's no requirement that a child Request retain a reference to its
061  // parent Request.
062  public <J> Request<J> child(final BeanReduction<J> beanReduction);
063
064  @SuppressWarnings("unchecked")
065  public default <R> R reference(final AttributedType attributedType) {
066    return this.reference(attributedType, (Creation<R>)this);
067  }
068
069}