From d77f25c3f1ac6a87081b92d9755f11f63056a163 Mon Sep 17 00:00:00 2001 From: Laird Nelson Date: Fri, 20 Feb 2026 23:09:11 -0800 Subject: [PATCH] Road grading; uptakes microbean-bean 0.0.23, microbean-construct 0.0.24 and microbean-proxy 0.0.6 Signed-off-by: Laird Nelson --- .../mvn-release-prepare-perform.yaml | 8 +- .github/workflows/mvn-verify.yaml | 8 +- README.md | 12 +- pom.xml | 18 +-- .../microbean/reference/ClientProxier.java | 2 +- .../microbean/reference/DestructorTree.java | 5 +- .../reference/ReflectiveClientProxier.java | 120 ------------------ .../java/org/microbean/reference/Request.java | 66 +++++----- 8 files changed, 62 insertions(+), 177 deletions(-) delete mode 100644 src/main/java/org/microbean/reference/ReflectiveClientProxier.java diff --git a/.github/workflows/mvn-release-prepare-perform.yaml b/.github/workflows/mvn-release-prepare-perform.yaml index d12a45b..3a93fc1 100644 --- a/.github/workflows/mvn-release-prepare-perform.yaml +++ b/.github/workflows/mvn-release-prepare-perform.yaml @@ -24,20 +24,20 @@ jobs: steps: - id: 'checkout' name: 'Step: Check Out Project' - uses: 'actions/checkout@v4' + uses: 'actions/checkout@v6' with: fetch-depth: 1 persist-credentials: false - id: 'setup-java' name: 'Step: Set Up Java and Maven' - uses: 'actions/setup-java@v4' + uses: 'actions/setup-java@v5' with: cache: 'maven' distribution: 'temurin' gpg-passphrase: 'GPG_PASSPHRASE' gpg-private-key: '${{ secrets.GPG_PRIVATE_KEY }}' - java-version: '24' - mvn-toolchain-id: 'Temurin 24' + java-version: '25' + mvn-toolchain-id: 'Temurin 25' mvn-toolchain-vendor: 'openjdk' # see ../../pom.xml server-id: 'central.sonatype.com' server-password: 'CENTRAL_SONATYPE_COM_PASSWORD' diff --git a/.github/workflows/mvn-verify.yaml b/.github/workflows/mvn-verify.yaml index a9a759e..faefc80 100644 --- a/.github/workflows/mvn-verify.yaml +++ b/.github/workflows/mvn-verify.yaml @@ -12,18 +12,18 @@ jobs: steps: - id: 'checkout' name: 'Step: Checkout' - uses: 'actions/checkout@v4' + uses: 'actions/checkout@v6' with: fetch-depth: 1 persist-credentials: false - id: 'setup-java' name: 'Step: Set Up Java and Maven' - uses: 'actions/setup-java@v4' + uses: 'actions/setup-java@v5' with: cache: 'maven' distribution: 'temurin' - java-version: '24' - mvn-toolchain-id: 'Temurin 24' + java-version: '25' + mvn-toolchain-id: 'Temurin 25' mvn-toolchain-vendor: 'openjdk' # see ../../pom.xml - id: 'mvn-verify' name: 'Step: Maven Verify' diff --git a/README.md b/README.md index b7f98cc..25c04ae 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # microBean™ Reference -[![Maven Central](https://img.shields.io/maven-central/v/org.microbean/microbean-reference.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.microbean/microbean-reference) +[![Maven +Central](https://img.shields.io/maven-central/v/org.microbean/microbean-reference.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/org.microbean/microbean-reference) + +![0% AI](https://img.shields.io/badge/%F0%9F%A4%96_AI-0%25_%F0%9F%8C%BC-brightgreen) The microBean™ Reference project provides classes and interfaces assisting with implementing contextual references. @@ -19,15 +22,16 @@ microBean™ Reference requires a Java runtime of version 21 or higher. # Installation -microBean™ Reference is available on [Maven Central](https://search.maven.org/). Include microBean™ Reference as a +microBean™ Reference is available on [Maven +Central](https://central.sonatype.com/artifact/org.microbean/microbean-reference). Include microBean™ Reference as a Maven dependency: ```xml org.microbean microbean-reference - - 0.0.5 + + 0.0.6 ``` diff --git a/pom.xml b/pom.xml index 6da3a3a..c5be22b 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ ${project.organization.name}. All rights reserved.]]> <a href="${project.url}" target="_top"><span style="font-family:Lobster, cursive;">µb</span> ${project.artifactId}</a> ${project.version} - https://microbean.github.io/microbean-attributes/apidocs/,https://microbean.github.io/microbean-bean/apidocs/,https://microbean.github.io/microbean-construct/apidocs/,https://microbean.github.io/microbean-proxy/apidocs/ + https://microbean.github.io/microbean-bean/apidocs/,https://microbean.github.io/microbean-construct/apidocs/,https://microbean.github.io/microbean-proxy/apidocs/ 2 @@ -130,19 +130,19 @@ org.microbean microbean-bean - 0.0.22 + 0.0.23 org.microbean microbean-construct - 0.0.18 + 0.0.24 org.microbean microbean-proxy - 0.0.5 + 0.0.6 @@ -309,7 +309,7 @@ com.puppycrawl.tools checkstyle - 12.3.0 + 13.2.0 @@ -330,7 +330,7 @@ maven-compiler-plugin - 3.14.1 + 3.15.0 -Xlint:all @@ -340,7 +340,7 @@ maven-dependency-plugin - 3.9.0 + 3.10.0 maven-deploy-plugin @@ -442,7 +442,7 @@ org.codehaus.mojo versions-maven-plugin - 2.20.1 + 2.21.0 io.smallrye @@ -452,7 +452,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.9.0 + 0.10.0 true central.sonatype.com diff --git a/src/main/java/org/microbean/reference/ClientProxier.java b/src/main/java/org/microbean/reference/ClientProxier.java index 75e1779..12fdd2b 100644 --- a/src/main/java/org/microbean/reference/ClientProxier.java +++ b/src/main/java/org/microbean/reference/ClientProxier.java @@ -1,6 +1,6 @@ /* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- * - * Copyright © 2023–2025 microBean™. + * Copyright © 2023–2026 microBean™. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at diff --git a/src/main/java/org/microbean/reference/DestructorTree.java b/src/main/java/org/microbean/reference/DestructorTree.java index b34d91a..f4d5967 100644 --- a/src/main/java/org/microbean/reference/DestructorTree.java +++ b/src/main/java/org/microbean/reference/DestructorTree.java @@ -1,6 +1,6 @@ /* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- * - * Copyright © 2025 microBean™. + * Copyright © 2025–2026 microBean™. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -25,9 +25,6 @@ * * @see DestructorRegistry */ -// Needed and used only by ReferencesSelector implementations. -// -// TODO: maybe could move it to microbean-reference? microbean-scopelet depends on microbean-reference already? public interface DestructorTree extends AutoCloseable, DestructorRegistry { /** diff --git a/src/main/java/org/microbean/reference/ReflectiveClientProxier.java b/src/main/java/org/microbean/reference/ReflectiveClientProxier.java deleted file mode 100644 index 9fe83e1..0000000 --- a/src/main/java/org/microbean/reference/ReflectiveClientProxier.java +++ /dev/null @@ -1,120 +0,0 @@ -/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- - * - * Copyright © 2025 microBean™. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package org.microbean.reference; - -import java.lang.invoke.MethodHandles.Lookup; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; - -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import java.util.concurrent.ConcurrentHashMap; - -import java.util.function.Function; -import java.util.function.Supplier; - -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; - -import javax.lang.model.element.TypeElement; - -import org.microbean.bean.Id; - -import org.microbean.construct.Domain; - -import org.microbean.proxy.AbstractReflectiveProxier; -import org.microbean.proxy.Proxy; -import org.microbean.proxy.ProxySpecification; - -import static java.lang.invoke.MethodHandles.publicLookup; - -import static java.lang.reflect.Proxy.newProxyInstance; - -/** - * An {@link AbstractReflectiveProxier} implementation that uses {@link java.lang.reflect.Proxy java.lang.reflect.Proxy} - * machinery. - * - * @author Laird Nelson - */ -public class ReflectiveClientProxier extends AbstractReflectiveProxier implements ClientProxier { - - private static final Lookup lookup = publicLookup(); - - private static final Map proxyInstances = new ConcurrentHashMap<>(); - - /** - * Creates a new {@link ReflectiveClientProxier}. - * - * @param domain a {@link Domain}; must not be {@code null} - * - * @exception NullPointerException if {@code domain} is {@code null} - */ - public ReflectiveClientProxier(final Domain domain) { - super(domain); - } - - @Override // ClientProxier - public R clientProxy(final Id id, final Supplier instanceSupplier) { - return this.proxy(new ProxySpecification(this.domain(), id), instanceSupplier).$cast(); - } - - /** - * Returns a {@link Proxy} appropriate for the supplied {@linkplain ProxySpecification specification} and {@link - * Supplier} of contextual instances. - * - * @param the contextual instance type - * - * @param ps an appropriate {@linkplain ProxySpecification proxy specification}; must not be {@code null} - * - * @param interfaces the interfaces to implement; every element is guaranteed to {@linkplain Class#isInterface() be an - * interface} - * - * @param instanceSupplier a {@link Supplier} of contextual instances; must not be {@code null}; may or may not create - * a new contextual instance each time it is invoked; may or may not be invoked multiple times depending on the - * subclass implementation - * - * @return a non-{@code null} {@link Proxy} - * - * @exception NullPointerException if any argument is {@code null} - */ - @Override // AbstractReflectiveProxier - @SuppressWarnings("unchecked") - protected final Proxy proxy(final ProxySpecification ps, - final Class[] interfaces, - final Supplier instanceSupplier) { - return - (Proxy)proxyInstances - .computeIfAbsent(ps, - ps0 -> newProxyInstance(this.classLoader(), - interfaces, - // Anonymous class, not lambda, due to Throwable in the signature - new InvocationHandler() { - @Override // InvocationHandler - public final Object invoke(final Object p, - final Method m, - final Object[] a) - throws Throwable { - return switch (m) { - case Method x when equalsMethod(x) -> p == a[0]; - case Method x when hashCodeMethod(x) -> System.identityHashCode(p); - default -> m.invoke(instanceSupplier.get(), a); - }; - } - })); - } - -} diff --git a/src/main/java/org/microbean/reference/Request.java b/src/main/java/org/microbean/reference/Request.java index b4e224a..85cd7dd 100644 --- a/src/main/java/org/microbean/reference/Request.java +++ b/src/main/java/org/microbean/reference/Request.java @@ -1,6 +1,6 @@ /* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- * - * Copyright © 2025 microBean™. + * Copyright © 2025–2026 microBean™. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -17,7 +17,11 @@ import java.util.function.Supplier; -import org.microbean.assign.AttributedType; +import javax.lang.model.AnnotatedConstruct; + +import javax.lang.model.type.TypeMirror; + +import org.microbean.assign.Annotated; import org.microbean.assign.Selectable; import org.microbean.bean.Bean; @@ -37,8 +41,8 @@ import static java.util.Objects.requireNonNull; /** - * A central object representing a request for dependencies that is a {@link Creation} (and therefore also a {@link - * Destruction}), a {@link DestructorRegistry}, and a {@link References}. + * A central object representing a request for dependencies that is a {@link Creation} (and therefore also, per + * contract, a {@link Destruction}), a {@link DestructorRegistry}, and a {@link References}. * *

Instances of this class are the heart and soul of a dependency injection and acquisition system.

* @@ -70,7 +74,7 @@ public final class Request implements Creation, Destruction, Destructor private final Domain domain; - private final Selectable> beans; + private final Selectable, Bean> beans; private final Instances instances; @@ -80,7 +84,7 @@ public final class Request implements Creation, Destruction, Destructor private final Bean b; // nullable; B and R must then be (effectively) Void - private final AttributedType rType; // nullable; R must then be Void + private final Annotated rConstruct; // nullable; R must then be Void /* @@ -93,7 +97,7 @@ public final class Request implements Creation, Destruction, Destructor * * @param d a {@link Domain}; must not be {@code null} * - * @param s a {@link Selectable} providing access to {@link Bean}s by {@link AttributedType}; must not be {@code + * @param s a {@link Selectable} providing access to {@link Bean}s by {@link AnnotatedConstruct}; must not be {@code * null}; must be safe for concurrent use by multiple threads; often assembled out of methods present in the {@link * org.microbean.bean.Selectables} and {@link org.microbean.bean.Beans} classes, among other such utility classes * @@ -107,7 +111,7 @@ public final class Request implements Creation, Destruction, Destructor * @see #Request(Domain, Selectable, Instances, DestructorTree, ClientProxier) */ public Request(final Domain d, - final Selectable> s, + final Selectable, Bean> s, final Instances instances, final ClientProxier cp) { this(d, s, instances, null, cp, null, null); @@ -118,7 +122,7 @@ public Request(final Domain d, * * @param d a {@link Domain}; must not be {@code null} * - * @param s a {@link Selectable} providing access to {@link Bean}s by {@link AttributedType}; must not be {@code + * @param s a {@link Selectable} providing access to {@link Bean}s by {@link AnnotatedConstruct}; must not be {@code * null}; must be safe for concurrent use by multiple threads; often assembled out of methods present in the {@link * org.microbean.bean.Selectables} and {@link org.microbean.bean.Beans} classes, among other such utility classes * @@ -133,7 +137,7 @@ public Request(final Domain d, * @exception NullPointerException if {@code s}, {@code instances}, or {@code cp} is {@code null} */ public Request(final Domain d, - final Selectable> s, + final Selectable, Bean> s, final Instances instances, final DestructorTree destructorTree, // nullable final ClientProxier cp) { @@ -141,19 +145,19 @@ public Request(final Domain d, } private Request(final Domain d, - final Selectable> s, + final Selectable, Bean> s, final Instances instances, final DestructorTree destructorTree, // nullable final ClientProxier cp, final Bean b, // nullable - final AttributedType rType) { // the type of the references returned (); nullable + final Annotated rConstruct) { // the type of the references returned (); nullable this.domain = requireNonNull(d, "d"); this.beans = requireNonNull(s, "s"); this.instances = requireNonNull(instances, "instances"); this.cp = requireNonNull(cp, "cp"); this.destructorTree = destructorTree == null ? new DefaultDestructorTree() : destructorTree; this.b = b; - this.rType = rType; + this.rConstruct = rConstruct; } @@ -201,16 +205,16 @@ public final R reference(final Bean bean) { @Override // ReferencesSelector @SuppressWarnings("unchecked") - public final References references(final AttributedType rType) { - return this.rType == rType ? (References)this : - // This basically returns "this" but with a new rType. But Request is immutable so we make a copy. + public final References references(final Annotated rConstruct) { + return this.rConstruct == rConstruct ? (References)this : + // This basically returns "this" but with a new rConstruct. But Request is immutable so we make a copy. new Request<>(this.domain, - this.beans, - this.instances, - this.destructorTree, // deliberately NO this.destructorTree.newChild() call - this.cp, - this.b, // nullable; will then be (effectively) Void - rType); // nullable; will then be Void + this.beans, + this.instances, + this.destructorTree, // deliberately NO this.destructorTree.newChild() call + this.cp, + this.b, // nullable; will then be (effectively) Void + rConstruct); // nullable; will then be Void } @Override // DestructorTree (DestructorRegistry) @@ -220,7 +224,7 @@ public final boolean register(final Object reference, final Destructor destructo @Override // References public final int size() { - return this.rType == null ? 0 : this.beans.select(this.rType).size(); + return this.rConstruct == null ? 0 : this.beans.select(this.rConstruct).size(); } /* @@ -228,7 +232,7 @@ public final int size() { */ private final Iterator> beanIterator() { - return this.rType == null ? emptyIterator() : this.beans.select(this.rType).iterator(); + return this.rConstruct == null ? emptyIterator() : this.beans.select(this.rConstruct).iterator(); } @SuppressWarnings("unchecked") @@ -242,12 +246,12 @@ private final Iterator> beanIterator() { } return new Request(this.domain, - this.beans, - this.instances, - this.destructorTree.newChild(), // critical; !b.equals(this.b) - this.cp, - b, // nullable; if so, better resolve to Void - null); // rType; resolves to Void + this.beans, + this.instances, + this.destructorTree.newChild(), // critical; !b.equals(this.b) + this.cp, + b, // nullable; if so, better resolve to Void + null); // rConstruct; resolves to Void } @@ -265,7 +269,7 @@ private final class ReferencesIterator implements Iterator { private ReferencesIterator() { super(); - if (rType == null) { + if (Request.this.rConstruct == null) { this.i = emptyIterator(); } }