001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2023–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
016import java.util.SequencedSet;
017
018// Subordinate to Factory<I> (really to Initializer<I>)
019// Akin to CDI's Producer.
020// Handles instance production and disposal, *including intercepted production*.
021// Does NOT handle initialization; see for example https://github.com/search?q=repo%3Aweld%2Fcore+%22.produce%28%29%22+language%3AJava&type=code
022// Does NOT handle post-initialization.
023// Does NOT handle business method interception.
024// Does NOT handle pre-disposal.
025// See also: InterceptingProducer
026@FunctionalInterface
027public interface Producer<I> extends Aggregate {
028
029  public default void dispose(final I i, final Request<I> r) {
030    if (i instanceof AutoCloseable ac) {
031      try {
032        ac.close();
033      } catch (final RuntimeException | Error e) {
034        throw e;
035      } catch (final InterruptedException e) {
036        Thread.currentThread().interrupt();
037        throw new DestructionException(e.getMessage(), e);
038      } catch (final Exception e) {
039        throw new DestructionException(e.getMessage(), e);
040      }
041    }
042  }
043
044  public default I produce(final Request<?> r) {
045    return this.produce(this.assign(r));
046  }
047
048  /**
049   * Produces a new contextual instance and returns it, possibly (often) making use of the supplied, dependent,
050   * contextual references.
051   *
052   * <p>Implementations of this method must not call {@link #produce(Request)} or an infinite loop may result.</p>
053   *
054   * @param assignments a {@link SequencedSet} of {@link Assignment}s this {@link Producer} needs to create the
055   * contextual instance; must not be {@code null}
056   *
057   * @return a new contextual instance, or {@code null}
058   *
059   * @exception NullPointerException if {@code dependentContextualReferences} is {@code null}
060   */
061  public I produce(final SequencedSet<? extends Assignment<?>> assignments);
062
063}