Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ changes, regardless of project version and without notice.**

# Requirements

microBean™ Assign requires a Java runtime of version 23 or higher.
microBean™ Assign requires a Java runtime of version 21 or higher.

# Installation

Expand All @@ -27,7 +27,7 @@ dependency:
<groupId>org.microbean</groupId>
<artifactId>microbean-assign</artifactId>
<!-- Always check https://search.maven.org/artifact/org.microbean/microbean-bean for up-to-date available versions. -->
<version>0.0.5</version>
<version>0.0.6</version>
</dependency>
```

Expand Down
37 changes: 21 additions & 16 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
<java.util.logging.config.file>${project.basedir}/src/test/java/logging.properties</java.util.logging.config.file>

<!-- maven-compiler-plugin properties -->
<maven.compiler.release>23</maven.compiler.release>
<maven.compiler.release>21</maven.compiler.release>
<maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
<maven.compiler.showWarnings>true</maven.compiler.showWarnings>

Expand Down Expand Up @@ -125,7 +125,7 @@
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.11.3</version>
<version>5.13.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand All @@ -135,13 +135,19 @@
<dependency>
<groupId>org.microbean</groupId>
<artifactId>microbean-attributes</artifactId>
<version>0.0.2</version>
<version>0.0.3</version>
</dependency>

<dependency>
<groupId>org.microbean</groupId>
<artifactId>microbean-constant</artifactId>
<version>0.0.7</version>
</dependency>

<dependency>
<groupId>org.microbean</groupId>
<artifactId>microbean-construct</artifactId>
<version>0.0.10</version>
<version>0.0.11</version>
</dependency>

</dependencies>
Expand All @@ -154,7 +160,13 @@
<artifactId>microbean-attributes</artifactId>
<scope>compile</scope>
</dependency>


<dependency>
<groupId>org.microbean</groupId>
<artifactId>microbean-constant</artifactId>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.microbean</groupId>
<artifactId>microbean-construct</artifactId>
Expand Down Expand Up @@ -308,7 +320,7 @@
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.0</version>
<configuration>
<filesets>
<fileset>
Expand Down Expand Up @@ -423,14 +435,7 @@
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit-platform</artifactId>
<version>3.5.2</version>
</dependency>
</dependencies>
<version>3.5.3</version>
</plugin>
<plugin>
<artifactId>maven-toolchains-plugin</artifactId>
Expand All @@ -439,7 +444,7 @@
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.9.1.0</version>
<version>4.9.3.0</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
Expand All @@ -449,7 +454,7 @@
<plugin>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.2.7</version>
<version>3.3.1</version>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
Expand Down
1 change: 1 addition & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

requires transitive java.compiler;
requires transitive org.microbean.attributes;
requires org.microbean.constant;
requires transitive org.microbean.construct;

}
93 changes: 93 additions & 0 deletions src/main/java/org/microbean/assign/Aggregate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* -*- 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.assign;

import java.util.Collection;
import java.util.Collections;
import java.util.SequencedSet;

import java.util.function.Function;

import static java.util.Collections.unmodifiableSequencedSet;

import static java.util.LinkedHashSet.newLinkedHashSet;

/**
* An object with {@linkplain AttributedElement dependencies}.
*
* <p>By default, {@link Aggregate}s have {@linkplain #EMPTY_DEPENDENCIES no dependencies}.</p>
*
* @author <a href="https://about.me/lairdnelson/" target="_top">Laird Nelson</a>
*
* @see #dependencies()
*/
public interface Aggregate {


/*
* Static fields.
*/


/**
* An immutable, empty {@link SequencedSet} of {@link Assignment}s.
*/
public static final SequencedSet<Assignment<?>> EMPTY_ASSIGNMENTS = unmodifiableSequencedSet(newLinkedHashSet(0));

/**
* An immutable, empty {@link SequencedSet} of {@link AttributedElement}s.
*/
public static final SequencedSet<AttributedElement> EMPTY_DEPENDENCIES = unmodifiableSequencedSet(newLinkedHashSet(0));


/*
* Default instance methods.
*/


/**
* Returns an immutable {@link SequencedSet} of {@link AttributedElement} instances.
*
* @return an immutable {@link SequencedSet} of {@link AttributedElement} instances; never {@code null}
*
* @see AttributedElement
*/
public default SequencedSet<AttributedElement> dependencies() {
return EMPTY_DEPENDENCIES;
}

/**
* A convenience method that assigns a contextual reference to each of this {@link Aggregate}'s {@link
* AttributedElement} instances and returns the resulting {@link SequencedSet} of {@link Assignment}s.
*
* <p>Typically there is no need to override this method.</p>
*
* @param r a {@link Function} that retrieves a contextual reference suitable for an {@link AttributedType}; if {@link
* #dependencies()} returns a non-empty {@link SequencedSet} then this argument must not be {@code null}
*
* @return an immutable {@link SequencedSet} of {@link Assignment} instances; never {@code null}
*
* @exception NullPointerException if {@code r} is {@code null}
*/
public default SequencedSet<? extends Assignment<?>> assign(final Function<? super AttributedType, ?> r) {
final Collection<? extends AttributedElement> ds = this.dependencies();
if (ds == null || ds.isEmpty()) {
return EMPTY_ASSIGNMENTS;
}
final SequencedSet<Assignment<?>> assignments = newLinkedHashSet(ds.size());
ds.forEach(d -> assignments.add(new Assignment<>(d, r.apply(d.attributedType()))));
return Collections.unmodifiableSequencedSet(assignments);
}

}
45 changes: 45 additions & 0 deletions src/main/java/org/microbean/assign/Assignment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* -*- 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.assign;

import java.util.Objects;

/**
* An assignment of a value to an {@link AttributedElement}.
*
* @param <R> the value type
*
* @param assignee the {@link AttributedElement}; must not be {@code null}
*
* @param value the value; may be {@code null}
*
* @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a>
*/
// You're going to be tempted to replace the value component with a Supplier component. Don't do it. An assignment is a
// value that belongs to, e.g., a field, so even if the value "came from" none/dependent/prototype scope, it was already
// sourced and "belongs to" the field.
public final record Assignment<R>(AttributedElement assignee, R value) {

/**
* Creates a new {@link Assignment}.
*
* @param assignee the {@link AttributedElement}; must not be {@code null}
*
* @param value the contextual reference; may be {@code null}
*/
public Assignment {
Objects.requireNonNull(assignee, "assignee");
}

}
102 changes: 102 additions & 0 deletions src/main/java/org/microbean/assign/AttributedElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* -*- 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.assign;

import java.lang.constant.ClassDesc;
import java.lang.constant.Constable;
import java.lang.constant.ConstantDesc;
import java.lang.constant.DynamicConstantDesc;
import java.lang.constant.MethodHandleDesc;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.lang.model.element.Element;

import javax.lang.model.type.TypeMirror;

import org.microbean.attributes.Attributed;
import org.microbean.attributes.Attributes;

import org.microbean.constant.Constables;

import static java.lang.constant.ConstantDescs.BSM_INVOKE;
import static java.lang.constant.ConstantDescs.CD_List;

/**
* A pairing of an {@link Element} with a {@link List} of {@link Attributes}s.
*
* @param element an {@link Element}
*
* @param attributes a {@link List} of {@link Attributes}s
*
* @author <a href="https://about.me/lairdnelson/" target="_top">Laird Nelson</a>
*/
public final record AttributedElement(Element element, List<Attributes> attributes) implements Attributed, Constable {

/**
* Creates a new {@link AttributedElement}.
*
* @param element a {@link Element}; must not be {@code null}
*
* @param attributes a {@link List} of {@link Attributes}; must not be {@code null}
*
* @exception NullPointerException if either argument is {@code null}
*/
public AttributedElement {
Objects.requireNonNull(element, "element");
attributes = List.copyOf(attributes);
}

/**
* Returns this {@link AttributedElement}'s {@linkplain Element#asType() type}.
*
* @return this {@link AttributedElement}'s {@linkplain Element#asType() type}; never {@code null}
*/
public final TypeMirror type() {
return this.element().asType();
}

/**
* Returns this {@link AttributedElement}'s {@link AttributedType}.
*
* @return this {@link AttributedElement}'s {@link AttributedType}; never {@code null}
*
* @see AttributedType
*/
public final AttributedType attributedType() {
return new AttributedType(this.type(), this.attributes());
}

/**
* Returns an {@link Optional} containing a {@link ConstantDesc} describing this {@link AttributedType}, or an
* {@linkplain Optional#isEmpty() empty <code>Optional</code>} if it could not be described.
*
* @return an {@link Optional} containing a {@link ConstantDesc} describing this {@link AttributedType}, or an
* {@linkplain Optional#isEmpty() empty <code>Optional</code>} if it could not be describe; never {@code null}
*/
@Override // Constable
public Optional<? extends ConstantDesc> describeConstable() {
return this.element() instanceof Constable e ? e.describeConstable() : Optional.<ConstantDesc>empty()
.flatMap(elementDesc -> Constables.describeConstable(this.attributes())
.map(attributesDesc -> DynamicConstantDesc.of(BSM_INVOKE,
MethodHandleDesc.ofConstructor(ClassDesc.of(this.getClass().getName()),
ClassDesc.of("javax.lang.model.element.Element"),
CD_List),
elementDesc,
attributesDesc)));
}

}
Loading