From d45121fcf9cf7dc9b3a88d8e27ce4e54e96172d5 Mon Sep 17 00:00:00 2001 From: Laird Nelson Date: Fri, 19 Dec 2025 18:28:09 -0800 Subject: [PATCH] Uptakes microbean-assign 0.0.11. Exposes model package. Signed-off-by: Laird Nelson --- README.md | 2 +- pom.xml | 2 +- src/main/java/module-info.java | 1 + src/main/java/org/microbean/bean/Bean.java | 5 + .../microbean/bean/BeanQualifiersMatcher.java | 38 ++- .../java/org/microbean/bean/Qualifiers.java | 254 ++++++++++++++++++ src/main/java/org/microbean/bean/Ranked.java | 2 +- .../java/org/microbean/bean/Selectables.java | 6 +- .../java/org/microbean/bean/model/Model.java | 147 ++++++++++ .../microbean/bean/model/package-info.java | 22 +- .../java/org/microbean/bean/TestBean.java | 20 +- .../org/microbean/bean/TestBeanSelection.java | 4 +- .../bean/TestConstableSemantics.java | 25 +- .../org/microbean/bean/TestQualifiers.java | 15 +- .../org/microbean/bean/TestSelectables.java | 7 +- .../microbean/bean/model/TestElements.java | 16 +- 16 files changed, 491 insertions(+), 75 deletions(-) create mode 100644 src/main/java/org/microbean/bean/Qualifiers.java create mode 100644 src/main/java/org/microbean/bean/model/Model.java diff --git a/README.md b/README.md index 1b6837e..b53055d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ dependency: org.microbean microbean-bean - 0.0.21 + 0.0.22 ``` diff --git a/pom.xml b/pom.xml index 75a7925..5718da8 100644 --- a/pom.xml +++ b/pom.xml @@ -130,7 +130,7 @@ org.microbean microbean-assign - 0.0.10 + 0.0.11 diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 8392da0..f47b114 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -20,6 +20,7 @@ module org.microbean.bean { exports org.microbean.bean; + exports org.microbean.bean.model; requires transitive java.compiler; requires transitive org.microbean.assign; diff --git a/src/main/java/org/microbean/bean/Bean.java b/src/main/java/org/microbean/bean/Bean.java index 2596e1f..f863eca 100644 --- a/src/main/java/org/microbean/bean/Bean.java +++ b/src/main/java/org/microbean/bean/Bean.java @@ -65,11 +65,13 @@ public final record Bean(Id id, Factory factory) implements Aggregate, Con requireNonNull(factory, "factory"); } + @Deprecated(forRemoval = true) @Override // Ranked public final boolean alternate() { return this.id.alternate(); } + // (Convenience.) @Override // Aggregate public final SequencedSet> assign(final Function r) { return this.factory.assign(r); @@ -89,6 +91,7 @@ public final Bean cast() { return (Bean)this; } + // (Convenience.) @Override // Aggregate public final SequencedSet dependencies() { return this.factory.dependencies(); @@ -120,6 +123,8 @@ public final int hashCode() { return this.id.hashCode(); } + // (Convenience.) + @Deprecated(forRemoval = true) @Override // Ranked public final int rank() { return this.id.rank(); diff --git a/src/main/java/org/microbean/bean/BeanQualifiersMatcher.java b/src/main/java/org/microbean/bean/BeanQualifiersMatcher.java index 18b6746..d7fe04b 100644 --- a/src/main/java/org/microbean/bean/BeanQualifiersMatcher.java +++ b/src/main/java/org/microbean/bean/BeanQualifiersMatcher.java @@ -16,12 +16,10 @@ import java.util.Collection; import org.microbean.assign.Matcher; -import org.microbean.assign.Qualifiers; import org.microbean.attributes.Attributes; -import static org.microbean.assign.Qualifiers.anyAndDefaultQualifiers; -import static org.microbean.assign.Qualifiers.defaultQualifier; +import static java.util.Objects.requireNonNull; /** * A {@link Matcher} encapsulating , Collection> { + /* + * Instance fields. + */ + + + private final Qualifiers qualifiers; + + /* * Constructors. */ @@ -42,9 +48,14 @@ public class BeanQualifiersMatcher implements Matcher receiverAttribu // "If an injection point declares no qualifier, the injection point has exactly one qualifier, the default // qualifier @Default." return - receiverQualifiers.isEmpty() ? payloadQualifiers.isEmpty() || payloadQualifiers.contains(defaultQualifier()) : - (payloadQualifiers.isEmpty() ? anyAndDefaultQualifiers() : payloadQualifiers).containsAll(receiverQualifiers); + receiverQualifiers.isEmpty() ? payloadQualifiers.isEmpty() || payloadQualifiers.contains(this.qualifiers.defaultQualifier()) : + (payloadQualifiers.isEmpty() ? this.qualifiers.anyAndDefaultQualifiers() : payloadQualifiers).containsAll(receiverQualifiers); } /** @@ -125,9 +136,12 @@ public final boolean test(final Collection receiverAttribu * Collection} that are deemed to be qualifiers; never {@code null} * * @exception NullPointerException if {@code as} is {@code null} + * + * @deprecated Pass a different {@link Qualifiers} to the {@link #BeanQualifiersMatcher(Qualifiers)} constructor. */ + @Deprecated(forRemoval = true) protected Collection qualifiers(final Collection as) { - return Qualifiers.qualifiers(as); + return this.qualifiers.qualifiers(as); } } diff --git a/src/main/java/org/microbean/bean/Qualifiers.java b/src/main/java/org/microbean/bean/Qualifiers.java new file mode 100644 index 0000000..1582c0f --- /dev/null +++ b/src/main/java/org/microbean/bean/Qualifiers.java @@ -0,0 +1,254 @@ +/* -*- 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.bean; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.microbean.attributes.Attributes; + +/** + * A {@link org.microbean.assign.Qualifiers} extended to work with commonly-used {@linkplain #anyQualifier() any}, + * {@linkplain #defaultQualifier() default}, and {@linkplain #primordialQualifier() primordial} qualifiers. + * + * @author Laird Nelson + * + * @see org.microbean.assign.Qualifiers + * + * @see Attributes + */ +public class Qualifiers extends org.microbean.assign.Qualifiers { + + private final Attributes ANY_QUALIFIER; + + private final List ANY_QUALIFIERS; + + private final Attributes DEFAULT_QUALIFIER; + + private final List DEFAULT_QUALIFIERS; + + private final List ANY_AND_DEFAULT_QUALIFIERS; + + private final Attributes PRIMORDIAL_QUALIFIER; + + private final List PRIMORDIAL_QUALIFIERS; + + /** + * Creates a new {@link Qualifiers}. + */ + public Qualifiers() { + super(); + this.ANY_QUALIFIER = Attributes.of("Any", this.qualifiers()); + this.ANY_QUALIFIERS = List.of(this.ANY_QUALIFIER); + + this.DEFAULT_QUALIFIER = Attributes.of("Default", this.qualifiers()); + this.DEFAULT_QUALIFIERS = List.of(this.DEFAULT_QUALIFIER); + + this.ANY_AND_DEFAULT_QUALIFIERS = List.of(ANY_QUALIFIER, DEFAULT_QUALIFIER); + + this.PRIMORDIAL_QUALIFIER = Attributes.of("Primordial", this.qualifiers()); + this.PRIMORDIAL_QUALIFIERS = List.of(PRIMORDIAL_QUALIFIER); + } + + /** + * Returns an unmodifiable {@link List} consisting solely of the unattributed any qualifier and the + * default qualifier. + * + * @return an unmodifiable {@link List} consisting solely of the unattributed any qualifier and the default qualifier; + * never {@code null} + * + * @see #anyQualifier() + * + * @see #defaultQualifier() + */ + public List anyAndDefaultQualifiers() { + return ANY_AND_DEFAULT_QUALIFIERS; + } + + /** + * Returns the unattributed any qualifier. + * + * @return the any qualifier; never {@code null} + * + * @see #anyQualifiers() + */ + public Attributes anyQualifier() { + return ANY_QUALIFIER; + } + + /** + * Returns {@code true} if and only if the supplied {@link Attributes} {@linkplain Attributes#equals(Object) is equal + * to} the unattributed {@linkplain #anyQualifier() any qualifier}. + * + * @param a an {@link Attributes}; must not be {@code null} + * + * @return {@code true} if and only if the supplied {@link Attributes} {@linkplain Attributes#equals(Object) is equal + * to} the unattributed {@linkplain #anyQualifier() any qualifier} + * + * @exception NullPointerException if {@code a} is {@code null} + */ + public boolean anyQualifier(final Attributes a) { + return this.anyQualifier() == a || this.anyQualifier().equals(a) && this.qualifier(a); + } + + /** + * Returns an immutable {@link List} consisting solely of the unattributed any qualifier. + * + * @return an immutable {@link List}; never {@code null} + * + * @see #anyQualifier() + */ + public List anyQualifiers() { + return ANY_QUALIFIERS; + } + + /** + * Returns the default qualifier. + * + * @return the default qualifier; never {@code null} + * + * @see #defaultQualifiers() + */ + public Attributes defaultQualifier() { + return DEFAULT_QUALIFIER; + } + + /** + * Returns {@code true} if and only if the supplied {@link Attributes} {@linkplain + * Attributes#equals(Object) is equal to} the {@linkplain #defaultQualifier() default qualifier}. + * + * @param a an {@link Attributes}; must not be {@code null} + * + * @return {@code true} if and only if the supplied {@link Attributes} {@linkplain + * Attributes#equals(Object) is equal to} the {@linkplain #defaultQualifier() default qualifier} + * + * @exception NullPointerException if {@code a} is {@code null} + */ + public boolean defaultQualifier(final Attributes a) { + return this.defaultQualifier() == a || this.defaultQualifier().equals(a) && qualifier(a); + } + + /** + * Returns an immutable {@link List} consisting solely of the default qualifier. + * + * @return an immutable {@link List}; never {@code null} + * + * @see #defaultQualifier() + */ + public List defaultQualifiers() { + return DEFAULT_QUALIFIERS; + } + + /** + * Returns an {@link Attributes} that is {@linkplain Attributes#equals(Object) equal to} the supplied {@link + * Attributes}. + * + *

The returned {@link Attributes} may be the supplied {@link Attributes} or a different instance.

+ * + * @param a an {@link Attributes}; must not be {@code null} + * + * @return an {@link Attributes} that is {@linkplain Attributes#equals(Object) equal to} the supplied {@link + * Attributes}; never {@code null} + * + * @exception NullPointerException if {@code a} is {@code null} + */ + public Attributes normalize(final Attributes a) { + return switch (a) { + case null -> throw new NullPointerException("a"); + case Attributes q when this.defaultQualifier(q) -> this.defaultQualifier(); + default -> super.normalize(a); + }; + } + + /** + * Returns an immutable {@link List} of {@link Attributes}s that is {@linkplain List#equals(Object) equal to} the + * supplied {@link List}. + * + *

The returned {@link List} may be the supplied {@link List} or a different instance.

+ * + * @param list a {@link List} of {@link Attributes}s; must not be {@code null} + * + * @return an immutable {@link List} of {@link Attributes}s that is {@linkplain List#equals(Object) equal to} the + * supplied {@link List}; never {@code null} + * + * @exception NullPointerException if {@code list} is {@code null} + */ + public List normalize(final List list) { + return switch (list.size()) { + case 0 -> List.of(); + case 1 -> list.equals(this.defaultQualifiers()) ? this.defaultQualifiers() : List.copyOf(list); + default -> super.normalize(list); + }; + } + + /** + * Returns the primordial qualifier. + * + * @return the primordial qualifier; never {@code null} + * + * @see #primordialQualifiers() + */ + public Attributes primordialQualifier() { + return PRIMORDIAL_QUALIFIER; + } + + /** + * Returns {@code true} if and only if the supplied {@link Attributes} {@linkplain + * Attributes#equals(Object) is equal to} the {@linkplain #primordialQualifier() primordial qualifier}. + * + * @param a an {@link Attributes}; must not be {@code null} + * + * @return {@code true} if and only if the supplied {@link Attributes} {@linkplain + * Attributes#equals(Object) is equal to} the {@linkplain #primordialQualifier() primordial qualifier} + * + * @exception NullPointerException if {@code a} is {@code null} + */ + public boolean primordialQualifier(final Attributes a) { + return this.primordialQualifier() == a || this.primordialQualifier().equals(a) && this.qualifier(a); + } + + /** + * Returns an immutable {@link List} consisting solely of the primordial qualifier. + * + * @return an immutable {@link List}; never {@code null} + * + * @see #primordialQualifier() + */ + public List primordialQualifiers() { + return PRIMORDIAL_QUALIFIERS; + } + + /** + * Returns an unmodifiable {@link List} consisting only of those {@link Attributes} in the supplied {@link + * Collection} that {@linkplain #qualifier(Attributes) are qualifiers}. + * + * @param c a {@link Collection} of {@link Attributes}s; must not be {@code null} + * + * @return an unmodifiable {@link List} consisting only of those {@link Attributes}s in the supplied {@link + * Collection} that {@linkplain #qualifier(Attributes) are qualifiers}; never {@code null} + * + * @exception NullPointerException if {@code c} is {@code null} + */ + public List qualifiers(final Collection c) { + return switch (c) { + case Collection c0 when c0.isEmpty() -> List.of(); + case Collection c0 when c0.equals(defaultQualifiers()) -> defaultQualifiers(); + case Collection c0 when c0.equals(anyAndDefaultQualifiers()) -> anyAndDefaultQualifiers(); + default -> super.qualifiers(c); + }; + } + +} diff --git a/src/main/java/org/microbean/bean/Ranked.java b/src/main/java/org/microbean/bean/Ranked.java index 8d76910..33d4f12 100644 --- a/src/main/java/org/microbean/bean/Ranked.java +++ b/src/main/java/org/microbean/bean/Ranked.java @@ -38,7 +38,7 @@ * * @deprecated This class is deprecated for future removal. */ -@Deprecated +@Deprecated(forRemoval = true) public interface Ranked { diff --git a/src/main/java/org/microbean/bean/Selectables.java b/src/main/java/org/microbean/bean/Selectables.java index 9d17802..33fcced 100644 --- a/src/main/java/org/microbean/bean/Selectables.java +++ b/src/main/java/org/microbean/bean/Selectables.java @@ -66,8 +66,8 @@ private Selectables() { * @exception NullPointerException if any argument is {@code null} */ public static final Selectable ambiguityReducing(final Selectable s, - final Predicate p, - final ToIntFunction ranker) { + final Predicate p, // are you an alternate? + final ToIntFunction ranker) { // rank? requireNonNull(s, "s"); requireNonNull(p, "p"); requireNonNull(ranker, "ranker"); @@ -80,7 +80,7 @@ public static final Selectable ambiguityReducing(final Selectable { - final List elements = s.select(c); + final List elements = s.select(c); // remember: c could be null; the result could be everything final int size = elements.size(); switch (size) { case 0: diff --git a/src/main/java/org/microbean/bean/model/Model.java b/src/main/java/org/microbean/bean/model/Model.java new file mode 100644 index 0000000..6d2457c --- /dev/null +++ b/src/main/java/org/microbean/bean/model/Model.java @@ -0,0 +1,147 @@ +/* -*- 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.bean.model; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import java.util.function.BiFunction; +import java.util.function.Function; + +import org.microbean.assign.Aggregate; +import org.microbean.assign.AttributedElement; +import org.microbean.assign.AttributedType; +import org.microbean.assign.Selectable; + +import org.microbean.bean.Bean; + +import static java.util.HashMap.newHashMap; + +import static java.util.HashSet.newHashSet; + +import static java.util.Objects.requireNonNull; + +import static java.util.stream.Collectors.toUnmodifiableSet; + +public final class Model { + + private final Set dependencyResolutions; + + private volatile boolean valid; + + private Model() { + this(Set.of()); + } + + private Model(Set dependencyResolutions) { + super(); + if (dependencyResolutions == null || dependencyResolutions.isEmpty()) { + this.dependencyResolutions = Set.of(); + this.valid = true; + } else { + this.dependencyResolutions = Set.copyOf(dependencyResolutions); + } + } + + @Override // Object + public final boolean equals(final Object other) { + return switch (other) { + case null -> false; + case Model m when this.getClass() == m.getClass() -> this.dependencyResolutions.equals(m.dependencyResolutions); + default -> false; + }; + } + + @Override // Object + public final int hashCode() { + return this.dependencyResolutions.hashCode(); + } + + public final boolean valid() { + if (this.valid) { // volatile read + return true; + } + for (final DependencyResolution dependencyResolution : this.dependencyResolutions) { + if (dependencyResolution.beans().size() != 1) { + return false; + } + } + this.valid = true; // volatile write + return true; + } + + public final Set ambiguousDependencyResolutions() { + return this.dependencyResolutions.stream().filter(DependencyResolution::ambiguous).collect(toUnmodifiableSet()); + } + + public final Set unsatisfiedDependencyResolutions() { + return this.dependencyResolutions.stream().filter(DependencyResolution::unsatisfied).collect(toUnmodifiableSet()); + } + + // So you can do: + // org.microbean.assign.Selectables.caching(selectable, model.toSelectionCache()); + public final BiFunction>>, ? extends List>> toSelectionCache() { + if (!this.valid()) { + throw new IllegalStateException("not valid"); + } + final Map>> m = newHashMap(this.dependencyResolutions.size()); // too big but whatever + for (final DependencyResolution r : this.dependencyResolutions) { + m.putIfAbsent(r.attributedType(), r.beans()); + } + return m::computeIfAbsent; // m is mutable on purpose; we can revisit if we decide that a Model is the absolute source of truth + } + + // s would normally be typesafeFiltering and ambiguityReducing but not necessarily cached + @SuppressWarnings("unchecked") + public static Model of(final Selectable> s) { + final Collection allBeans = s.select(null); + if (allBeans.isEmpty()) { + return new Model(Set.of()); + } + final Map>> m2 = newHashMap(allBeans.size() * 5); // estimate; + final Set dependencyResolutions = newHashSet(allBeans.size() * 5); + for (final Aggregate bean : allBeans) { + for (final AttributedElement dependency : bean.dependencies()) { + dependencyResolutions.add(new DependencyResolution(dependency, + m2.computeIfAbsent(dependency.attributedType(), + at -> (List>)s.select(at)))); + } + } + return new Model(dependencyResolutions); + } + + public static final record DependencyResolution(AttributedElement attributedElement, List> beans) { + + public DependencyResolution { + requireNonNull(attributedElement, "attributedElement"); + beans = beans == null ? List.of() : List.copyOf(beans); + } + + public final AttributedType attributedType() { + return this.attributedElement.attributedType(); + } + + public final boolean ambiguous() { + return this.beans().size() > 1; + } + + public final boolean unsatisfied() { + return this.beans().isEmpty(); + } + + } + +} diff --git a/src/main/java/org/microbean/bean/model/package-info.java b/src/main/java/org/microbean/bean/model/package-info.java index dfcb9ad..e4e3475 100644 --- a/src/main/java/org/microbean/bean/model/package-info.java +++ b/src/main/java/org/microbean/bean/model/package-info.java @@ -1,6 +1,6 @@ /* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- * - * Copyright © 2024 microBean™. + * Copyright © 2024–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 @@ -17,6 +17,26 @@ * *

This package is experimental, incomplete, and subject to change at any moment.

* + *

The general idea is:

+ * + *
    + * + *
  • You start with a list of {@link org.microbean.bean.Bean}s ({@link org.microbean.assign.Aggregate}s, really). Each + * element will have {@linkplain org.microbean.bean.Bean#dependencies() dependencies}. A dependency is represented by an + * {@link org.microbean.assign.AttributedElement}. (For any dependency, it will not represent the bean that supplies + * it.)
  • + * + *
  • From this list, you can extract a set of {@link org.microbean.assign.AttributedType}s. These represent + * all the demand in the system.
  • + * + *
  • For each such {@link org.microbean.assign.AttributedType}, you can perform typesafe resolution and find a {@link + * org.microbean.bean.Bean} that satisfies the demand.
  • + * + *
  • The resulting model should not have any "holes". That is, every {@link + * org.microbean.assign.AttributedType} should be matched up with exactly one {@link org.microbean.bean.Bean}.
  • + * + *
+ * * @author Laird Nelson */ package org.microbean.bean.model; diff --git a/src/test/java/org/microbean/bean/TestBean.java b/src/test/java/org/microbean/bean/TestBean.java index 45d7742..9507138 100644 --- a/src/test/java/org/microbean/bean/TestBean.java +++ b/src/test/java/org/microbean/bean/TestBean.java @@ -3,12 +3,12 @@ * Copyright © 2023–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 + * 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 + * 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.bean; @@ -17,7 +17,6 @@ import java.util.List; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.microbean.constant.Constables; @@ -28,34 +27,33 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.microbean.assign.Qualifiers.anyAndDefaultQualifiers; - final class TestBean { private static final Domain domain = new DefaultDomain(); private static final BeanTypes beanTypes = new BeanTypes(domain); - + + private static final Qualifiers qualifiers = new Qualifiers(); + private TestBean() { super(); } - @Disabled // types are not currently Constable @Test final void testConstableStuff() { final Factory f = new Constant<>("Hello"); final Id id = new Id(beanTypes.beanTypes(List.of(domain.declaredType("java.lang.String"), domain.javaLangObject().asType())), - anyAndDefaultQualifiers()); + qualifiers.anyAndDefaultQualifiers()); assertTrue(id instanceof Constable); - assertFalse(id.types().describeConstable().isEmpty()); // Constables.describeConstable(id.types()).isEmpty()); + assertFalse(id.types().describeConstable().isEmpty()); assertFalse(id.describeConstable().isEmpty()); } @Test final void testAnyAndDefaultQualifiersCanBeConstable() { - assertFalse(Constables.describeConstable(anyAndDefaultQualifiers()).isEmpty()); + assertFalse(Constables.describeConstable(qualifiers.anyAndDefaultQualifiers()).isEmpty()); } - + } diff --git a/src/test/java/org/microbean/bean/TestBeanSelection.java b/src/test/java/org/microbean/bean/TestBeanSelection.java index a836059..0db75e5 100644 --- a/src/test/java/org/microbean/bean/TestBeanSelection.java +++ b/src/test/java/org/microbean/bean/TestBeanSelection.java @@ -37,8 +37,10 @@ final class TestBeanSelection { private static final BeanTypes beanTypes = new BeanTypes(domain); + private static final Qualifiers qualifiers = new Qualifiers(); + private static final Matcher matcher = - new IdMatcher(new BeanTypeMatcher(domain), new BeanQualifiersMatcher()); + new IdMatcher(new BeanTypeMatcher(domain), new BeanQualifiersMatcher(qualifiers)); private TestBeanSelection() { super(); diff --git a/src/test/java/org/microbean/bean/TestConstableSemantics.java b/src/test/java/org/microbean/bean/TestConstableSemantics.java index 980c66e..2d150c6 100644 --- a/src/test/java/org/microbean/bean/TestConstableSemantics.java +++ b/src/test/java/org/microbean/bean/TestConstableSemantics.java @@ -3,36 +3,26 @@ * Copyright © 2023–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 + * 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 + * 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.bean; import java.lang.constant.Constable; -import java.lang.constant.DynamicConstantDesc; -import java.lang.constant.MethodHandleDesc; -import java.lang.constant.MethodTypeDesc; import java.lang.invoke.MethodHandles; -import java.util.Comparator; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; import javax.lang.model.type.TypeMirror; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.microbean.constant.Constables; @@ -47,21 +37,19 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static java.lang.invoke.MethodHandles.lookup; -import static org.microbean.assign.Qualifiers.anyAndDefaultQualifiers; - final class TestConstableSemantics { private static Domain domain; private static BeanTypes beanTypes; + private static Qualifiers qualifiers; + private TestConstableSemantics() { super(); } @@ -70,11 +58,12 @@ private TestConstableSemantics() { static final void initializeDomain() { domain = new DefaultDomain(); beanTypes = new BeanTypes(domain); + qualifiers = new Qualifiers(); } @Test final void testAnyAndDefaultQualifiersList() throws ReflectiveOperationException { - final List list = anyAndDefaultQualifiers(); + final List list = qualifiers.anyAndDefaultQualifiers(); assertEquals(list, Constables.describeConstable(list).orElseThrow().resolveConstantDesc(MethodHandles.lookup())); } @@ -128,7 +117,7 @@ final void testId() throws ReflectiveOperationException { final Id id = new Id(beanTypes.beanTypes(List.of(domain.typeElement("java.lang.String").asType(), domain.javaLangObject().asType())), - anyAndDefaultQualifiers()); + qualifiers.anyAndDefaultQualifiers()); final Id id2 = (Id)Constables.describeConstable(id) .orElseThrow() .resolveConstantDesc(lookup()); diff --git a/src/test/java/org/microbean/bean/TestQualifiers.java b/src/test/java/org/microbean/bean/TestQualifiers.java index 6ce559b..c1d3cd7 100644 --- a/src/test/java/org/microbean/bean/TestQualifiers.java +++ b/src/test/java/org/microbean/bean/TestQualifiers.java @@ -3,12 +3,12 @@ * Copyright © 2023–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 + * 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 + * 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.bean; @@ -23,26 +23,25 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.microbean.assign.Qualifiers.defaultQualifier; -import static org.microbean.assign.Qualifiers.qualifier; - final class TestQualifiers { + private static final Qualifiers qualifiers = new Qualifiers(); + private TestQualifiers() { super(); } @Test final void testDefaultQualifierStaticMethod() { - final Attributes dq = defaultQualifier(); + final Attributes dq = qualifiers.defaultQualifier(); assertEquals("Default", dq.name()); final Collection md = dq.attributes(dq.name()); assertEquals(1, md.size()); final Attributes q = md.iterator().next(); assertEquals("Qualifier", q.name()); assertTrue(q.values().isEmpty()); - assertTrue(qualifier(dq)); - assertFalse(qualifier(q)); + assertTrue(qualifiers.qualifier(dq)); + assertFalse(qualifiers.qualifier(q)); } } diff --git a/src/test/java/org/microbean/bean/TestSelectables.java b/src/test/java/org/microbean/bean/TestSelectables.java index 726fe84..f398a28 100644 --- a/src/test/java/org/microbean/bean/TestSelectables.java +++ b/src/test/java/org/microbean/bean/TestSelectables.java @@ -17,13 +17,8 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import static org.microbean.assign.Qualifiers.anyAndDefaultQualifiers; - final class TestSelectables { private TestSelectables() { @@ -40,5 +35,5 @@ final void testMethodReferenceAndNull() { } } - + } diff --git a/src/test/java/org/microbean/bean/model/TestElements.java b/src/test/java/org/microbean/bean/model/TestElements.java index b6046ba..6aa80a0 100644 --- a/src/test/java/org/microbean/bean/model/TestElements.java +++ b/src/test/java/org/microbean/bean/model/TestElements.java @@ -1,6 +1,6 @@ /* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- * - * Copyright © 2024 microBean™. + * Copyright © 2024–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 @@ -13,15 +13,7 @@ */ package org.microbean.bean.model; -import java.io.StringWriter; - -import java.util.ArrayList; -import java.util.List; - import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; - -import javax.lang.model.util.ElementFilter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -37,14 +29,14 @@ final class TestElements { private static final Domain domain = new DefaultDomain(); - + private TestElements() { super(); } @Test final void testStreamDepthFirst() { - final Element self = domain.typeElement(this.getClass().getName()); + final Element self = domain.typeElement(this.getClass().getCanonicalName()); assertTrue(self instanceof UniversalElement); Trees.streamDepthFirst(self, Elements::parametersAndEnclosedElements) .forEachOrdered(e -> System.out.println(e.getSimpleName() + " (" + e.getKind() + ")")); @@ -62,5 +54,5 @@ final void testBigHorkingStream() { private static final void frob(int a, int b) { class goop {}; } - + }