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.scopelet; 015 016import java.lang.constant.ClassDesc; 017import java.lang.constant.Constable; 018import java.lang.constant.DynamicConstantDesc; 019import java.lang.constant.MethodHandleDesc; 020 021import java.util.List; 022import java.util.Optional; 023 024import org.microbean.bean.AutoCloseableRegistry; 025import org.microbean.bean.Creation; 026import org.microbean.bean.DisposableReference; 027import org.microbean.bean.Factory; 028import org.microbean.bean.Id; 029import org.microbean.bean.ReferenceSelector; 030 031import static java.lang.constant.ConstantDescs.BSM_INVOKE; 032 033import static org.microbean.bean.Qualifiers.anyQualifier; 034 035import static org.microbean.lang.Lang.declaredType; 036import static org.microbean.lang.Lang.typeElement; 037 038import static org.microbean.scope.Scope.NONE_ID; 039import static org.microbean.scope.Scope.SINGLETON_ID; 040 041public final class NoneScopelet extends Scopelet<NoneScopelet> implements Constable { 042 043 public static final Id ID = 044 new Id(List.of(declaredType(NoneScopelet.class), 045 declaredType(null, 046 typeElement(Scopelet.class), 047 declaredType(NoneScopelet.class))), 048 List.of(NONE_ID, anyQualifier()), // qualifiers 049 SINGLETON_ID); // the scope we belong to 050 051 private static final ClassDesc CD_NoneScopelet = ClassDesc.of(NoneScopelet.class.getName()); 052 053 private static final boolean useDisposableReferences = 054 Boolean.parseBoolean(System.getProperty("useDisposableReferences", "false")); 055 056 public NoneScopelet() { 057 super(NONE_ID); // the scope we implement 058 } 059 060 @Override // Scopelet<NoneScopelet> 061 public final Id id() { 062 return ID; 063 } 064 065 @Override // Scopelet<NoneScopelet> 066 public final <I> I get(final Object beanId) { 067 if (!this.active()) { 068 throw new InactiveScopeletException(); 069 } 070 return null; 071 } 072 073 @Override // Scopelet<NoneScopelet> 074 public final <I> I instance(final Object beanId, 075 final Factory<I> factory, 076 final Creation<I> c, 077 final ReferenceSelector r) { 078 if (!this.active()) { 079 throw new InactiveScopeletException(); 080 } else if (factory == null) { 081 return null; 082 } 083 final I returnValue = factory.create(c, r); 084 if (factory.destroys()) { 085 if (useDisposableReferences) { 086 new DisposableReference<>(returnValue, referent -> factory.destroy(referent, c, c, r)); 087 } else if (c instanceof AutoCloseableRegistry acr) { 088 acr.register(new Instance<>(returnValue, factory::destroy, c, r)); 089 } 090 } 091 return returnValue; 092 } 093 094 @Override // Scopelet<NoneScopelet> 095 public final boolean remove(final Object id) { 096 if (!this.active()) { 097 throw new InactiveScopeletException(); 098 } 099 return false; 100 } 101 102 @Override // Constable 103 public final Optional<DynamicConstantDesc<NoneScopelet>> describeConstable() { 104 return Optional.of(DynamicConstantDesc.of(BSM_INVOKE, MethodHandleDesc.ofConstructor(CD_NoneScopelet))); 105 } 106 107}