This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch nullaway-annotations in repository https://gitbox.apache.org/repos/asf/maven.git
commit ffcc698dd111e4d02bc92544ad308a22cff6fcd5 Author: Guillaume Nodet <[email protected]> AuthorDate: Fri Mar 20 11:29:38 2026 +0100 Add @Nullable annotations to Maven 4 API and set up NullAway for compile-time null checks - Add opt-in NullAway profile (-Pnullaway) using Error Prone 2.36.0 + NullAway 0.12.6 for compile-time null safety checking on org.apache.maven.api packages - Add @Nullable annotations to fields, method parameters, and return types across the Maven 4 API where values can genuinely be null - Add @Nullable to Velocity model template (model.vm) for generated model classes: non-primitive, non-collection fields and their getters - Add @Nullable to hand-written template files: InputLocation, InputSource, InputLocationTracker, ImmutableCollections - Add @Nullable to XmlNode builder, XmlService merge methods, XmlReaderRequest, XmlWriterRequest - Add @Nullable to builder fields in request classes (fields start null before builder methods are called) - Add requireNonNull() validation in builder build() methods for parameters that must be non-null, preserving existing @Nonnull API contracts - Fix InputLocation.locations field: not nullable (always initialized via ImmutableCollections which returns empty map for null input) - Fix Sources.BuildPathSource.resolve() null safety for Path.getParent() - Add @Nullable to Nullable annotation itself (meta-annotation for NullAway) - Fix Phase.getEffectiveId() return annotation in lifecycle.mdo Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../org/apache/maven/api/annotations/Nullable.java | 3 + .../org/apache/maven/api/cli/ParserRequest.java | 44 +++++++-- .../maven/api/cli/logging/AccumulatingLogger.java | 5 +- .../java/org/apache/maven/api/DependencyScope.java | 2 + .../java/org/apache/maven/api/JavaPathType.java | 7 +- .../java/org/apache/maven/api/ProtoSession.java | 38 +++++--- .../main/java/org/apache/maven/api/Session.java | 39 ++++++-- .../org/apache/maven/api/feature/Features.java | 4 +- .../org/apache/maven/api/plugin/MojoException.java | 7 +- .../ArtifactCoordinatesFactoryRequest.java | 103 ++++++++++++++++----- .../api/services/ArtifactDeployerRequest.java | 14 ++- .../maven/api/services/ArtifactFactoryRequest.java | 59 ++++++++++-- .../api/services/ArtifactInstallerRequest.java | 7 +- .../api/services/ArtifactResolverRequest.java | 15 ++- .../maven/api/services/ArtifactResolverResult.java | 1 + .../org/apache/maven/api/services/BaseRequest.java | 6 +- .../DependencyCoordinatesFactoryRequest.java | 91 +++++++++++++----- .../api/services/DependencyResolverRequest.java | 39 +++++++- .../maven/api/services/MavenBuilderException.java | 2 +- .../apache/maven/api/services/MavenException.java | 7 +- .../maven/api/services/ModelBuilderRequest.java | 64 ++++++++++--- .../maven/api/services/ModelProblemCollector.java | 5 +- .../maven/api/services/PathMatcherFactory.java | 5 +- .../maven/api/services/ProjectBuilderRequest.java | 26 +++++- .../maven/api/services/RepositoryAwareRequest.java | 3 +- .../apache/maven/api/services/SettingsBuilder.java | 4 +- .../maven/api/services/SettingsBuilderRequest.java | 28 +++++- .../org/apache/maven/api/services/Sources.java | 14 ++- .../maven/api/services/ToolchainManager.java | 3 +- .../api/services/ToolchainsBuilderRequest.java | 20 +++- .../api/services/VersionRangeResolverRequest.java | 22 ++++- .../maven/api/services/VersionResolverRequest.java | 19 +++- .../maven/api/services/xml/XmlReaderRequest.java | 58 ++++++++++-- .../maven/api/services/xml/XmlWriterRequest.java | 41 ++++++-- .../maven/api/model/ModelObjectProcessor.java | 7 +- api/maven-api-model/src/main/mdo/maven.mdo | 16 ++-- api/maven-api-plugin/src/main/mdo/lifecycle.mdo | 1 + .../apache/maven/api/spi/ModelParserException.java | 9 +- .../maven/api/spi/ModelTransformerException.java | 7 +- .../apache/maven/api/xml/ImmutableCollections.java | 6 +- .../java/org/apache/maven/api/xml/XmlNode.java | 50 +++++++--- .../java/org/apache/maven/api/xml/XmlService.java | 13 ++- pom.xml | 47 ++++++++++ src/mdo/java/ImmutableCollections.java | 6 +- src/mdo/java/InputLocation.java | 33 ++++--- src/mdo/java/InputLocationTracker.java | 4 + src/mdo/java/InputSource.java | 32 +++++-- src/mdo/model.vm | 29 ++++-- 48 files changed, 847 insertions(+), 218 deletions(-) diff --git a/api/maven-api-annotations/src/main/java/org/apache/maven/api/annotations/Nullable.java b/api/maven-api-annotations/src/main/java/org/apache/maven/api/annotations/Nullable.java index df2517cad9..84cf081033 100644 --- a/api/maven-api-annotations/src/main/java/org/apache/maven/api/annotations/Nullable.java +++ b/api/maven-api-annotations/src/main/java/org/apache/maven/api/annotations/Nullable.java @@ -19,8 +19,10 @@ package org.apache.maven.api.annotations; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * The annotated element can be {@code null}. @@ -31,4 +33,5 @@ @Experimental @Documented @Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) public @interface Nullable {} diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/ParserRequest.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/ParserRequest.java index ee25ec63da..9c3ec06ca7 100644 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/ParserRequest.java +++ b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/ParserRequest.java @@ -279,12 +279,25 @@ class Builder { private final Logger logger; private Lookup lookup = EMPTY_LOOKUP; + + @Nullable private Path cwd; + + @Nullable private Path mavenHome; + + @Nullable private Path userHome; + + @Nullable private InputStream stdIn; + + @Nullable private OutputStream stdOut; + + @Nullable private OutputStream stdErr; + private boolean embedded = false; private Builder( @@ -361,12 +374,25 @@ private static class ParserRequestImpl implements ParserRequest { private final MessageBuilderFactory messageBuilderFactory; private final List<String> args; private final Lookup lookup; + + @Nullable private final Path cwd; + + @Nullable private final Path mavenHome; + + @Nullable private final Path userHome; + + @Nullable private final InputStream stdIn; + + @Nullable private final OutputStream stdOut; + + @Nullable private final OutputStream stdErr; + private final boolean embedded; private ParserRequestImpl( @@ -376,12 +402,12 @@ private ParserRequestImpl( Logger logger, MessageBuilderFactory messageBuilderFactory, Lookup lookup, - Path cwd, - Path mavenHome, - Path userHome, - InputStream stdIn, - OutputStream stdOut, - OutputStream stdErr, + @Nullable Path cwd, + @Nullable Path mavenHome, + @Nullable Path userHome, + @Nullable InputStream stdIn, + @Nullable OutputStream stdOut, + @Nullable OutputStream stdErr, boolean embedded) { this.command = requireNonNull(command, "command"); this.commandName = requireNonNull(commandName, "commandName"); @@ -428,31 +454,37 @@ public Lookup lookup() { return lookup; } + @Nullable @Override public Path cwd() { return cwd; } + @Nullable @Override public Path mavenHome() { return mavenHome; } + @Nullable @Override public Path userHome() { return userHome; } + @Nullable @Override public InputStream stdIn() { return stdIn; } + @Nullable @Override public OutputStream stdOut() { return stdOut; } + @Nullable @Override public OutputStream stdErr() { return stdErr; diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/logging/AccumulatingLogger.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/logging/AccumulatingLogger.java index 013e73a81a..2f2d425de4 100644 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/logging/AccumulatingLogger.java +++ b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/logging/AccumulatingLogger.java @@ -22,6 +22,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicReference; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.cli.Logger; import static java.util.Objects.requireNonNull; @@ -34,10 +35,10 @@ public class AccumulatingLogger implements Logger { private final AtomicReference<List<Entry>> entries = new AtomicReference<>(new CopyOnWriteArrayList<>()); @Override - public void log(Level level, String message, Throwable error) { + public void log(Level level, String message, @Nullable Throwable error) { requireNonNull(level, "level"); requireNonNull(message, "message"); - entries.get().add(new Entry(level, message, error)); + requireNonNull(entries.get()).add(new Entry(level, message, error)); } @Override diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyScope.java b/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyScope.java index f9f788e003..77f6cfc816 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyScope.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyScope.java @@ -26,6 +26,7 @@ import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Immutable; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.annotations.Nullable; /** * Indicates when the dependency will be used. @@ -106,6 +107,7 @@ public enum DependencyScope { * * @param id the identifier of the scope (case-sensitive) */ + @Nullable public static DependencyScope forId(String id) { return IDS.get(id); } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java b/api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java index bf5dc12a7f..aef3f91cdc 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java @@ -30,6 +30,7 @@ import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.annotations.Nullable; /** * The option of a Java command-line tool where to place the paths to some dependencies. @@ -170,6 +171,7 @@ public static Modular patchModule(@Nonnull String moduleName) { * * @see #location() */ + @Nullable private final JavaFileManager.Location location; /** @@ -177,6 +179,7 @@ public static Modular patchModule(@Nonnull String moduleName) { * * @see #option() */ + @Nullable private final String option; /** @@ -185,7 +188,7 @@ public static Modular patchModule(@Nonnull String moduleName) { * @param location the {@code javax.tool} enumeration value, or {@code null} if none. * @param option the Java tools option for this path, or {@code null} if none */ - JavaPathType(JavaFileManager.Location location, String option) { + JavaPathType(@Nullable JavaFileManager.Location location, @Nullable String option) { this.location = location; this.option = option; } @@ -260,7 +263,7 @@ public String[] option(Iterable<? extends Path> paths) { /** * Implementation shared with {@link Modular}. */ - final String[] format(String moduleName, Iterable<? extends Path> paths) { + final String[] format(@Nullable String moduleName, Iterable<? extends Path> paths) { if (option == null) { throw new IllegalStateException("No option is associated to this path type."); } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/ProtoSession.java b/api/maven-api-core/src/main/java/org/apache/maven/api/ProtoSession.java index 41300d074e..387165523f 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/ProtoSession.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/ProtoSession.java @@ -116,20 +116,29 @@ static Builder newBuilder() { } class Builder { + @Nullable private Map<String, String> userProperties; + + @Nullable private Map<String, String> systemProperties; + + @Nullable private Instant startTime; + + @Nullable private Path topDirectory; + + @Nullable private Path rootDirectory; private Builder() {} private Builder( - Map<String, String> userProperties, - Map<String, String> systemProperties, - Instant startTime, - Path topDirectory, - Path rootDirectory) { + @Nullable Map<String, String> userProperties, + @Nullable Map<String, String> systemProperties, + @Nullable Instant startTime, + @Nullable Path topDirectory, + @Nullable Path rootDirectory) { this.userProperties = userProperties; this.systemProperties = systemProperties; this.startTime = startTime; @@ -163,7 +172,12 @@ public Builder withRootDirectory(@Nullable Path rootDirectory) { } public ProtoSession build() { - return new Impl(userProperties, systemProperties, startTime, topDirectory, rootDirectory); + return new Impl( + requireNonNull(userProperties, "userProperties cannot be null"), + requireNonNull(systemProperties, "systemProperties cannot be null"), + requireNonNull(startTime, "startTime cannot be null"), + requireNonNull(topDirectory, "topDirectory cannot be null"), + rootDirectory); } private static class Impl implements ProtoSession { @@ -172,14 +186,16 @@ private static class Impl implements ProtoSession { private final Map<String, String> effectiveProperties; private final Instant startTime; private final Path topDirectory; + + @Nullable private final Path rootDirectory; private Impl( - Map<String, String> userProperties, - Map<String, String> systemProperties, - Instant startTime, - Path topDirectory, - Path rootDirectory) { + @Nonnull Map<String, String> userProperties, + @Nonnull Map<String, String> systemProperties, + @Nonnull Instant startTime, + @Nonnull Path topDirectory, + @Nullable Path rootDirectory) { this.userProperties = Map.copyOf(userProperties); this.systemProperties = Map.copyOf(systemProperties); Map<String, String> cp = new HashMap<>(systemProperties); diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java index 8ef3802062..71cd67685d 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java @@ -263,7 +263,11 @@ default Map<String, String> getEffectiveProperties() { * @see ArtifactCoordinatesFactory#create(Session, String, String, String, String) */ @Nonnull - ArtifactCoordinates createArtifactCoordinates(String groupId, String artifactId, String version, String extension); + ArtifactCoordinates createArtifactCoordinates( + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String extension); /** * Shortcut for {@code getService(ArtifactFactory.class).create(...)}. @@ -280,7 +284,12 @@ default Map<String, String> getEffectiveProperties() { */ @Nonnull ArtifactCoordinates createArtifactCoordinates( - String groupId, String artifactId, String version, String classifier, String extension, String type); + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String classifier, + @Nullable String extension, + @Nullable String type); /** * Shortcut for {@code getService(ArtifactFactory.class).create(...)}. @@ -327,7 +336,11 @@ ArtifactCoordinates createArtifactCoordinates( * @see org.apache.maven.api.services.ArtifactFactory#create(Session, String, String, String, String) */ @Nonnull - Artifact createArtifact(String groupId, String artifactId, String version, String extension); + Artifact createArtifact( + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String extension); /** * Shortcut for {@code getService(ArtifactFactory.class).create(...)}. @@ -344,7 +357,12 @@ ArtifactCoordinates createArtifactCoordinates( */ @Nonnull Artifact createArtifact( - String groupId, String artifactId, String version, String classifier, String extension, String type); + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String classifier, + @Nullable String extension, + @Nullable String type); /** * Shortcut for {@code getService(ArtifactFactory.class).createProduced(...)}. @@ -358,7 +376,11 @@ Artifact createArtifact( * @see org.apache.maven.api.services.ArtifactFactory#createProduced(Session, String, String, String, String) */ @Nonnull - ProducedArtifact createProducedArtifact(String groupId, String artifactId, String version, String extension); + ProducedArtifact createProducedArtifact( + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String extension); /** * Shortcut for {@code getService(ArtifactFactory.class).createProduced(...)}. @@ -375,7 +397,12 @@ Artifact createArtifact( */ @Nonnull ProducedArtifact createProducedArtifact( - String groupId, String artifactId, String version, String classifier, String extension, String type); + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String classifier, + @Nullable String extension, + @Nullable String type); /** * Shortcut for {@code getService(ArtifactResolver.class).resolve(...)}. diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/feature/Features.java b/api/maven-api-core/src/main/java/org/apache/maven/api/feature/Features.java index 52feae0cd8..20ada0c9cd 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/feature/Features.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/feature/Features.java @@ -61,11 +61,11 @@ public static boolean deployBuildPom(@Nullable Map<String, ?> userProperties) { return doGet(userProperties, Constants.MAVEN_DEPLOY_BUILD_POM, true); } - private static boolean doGet(Map<String, ?> userProperties, String key, boolean def) { + private static boolean doGet(@Nullable Map<String, ?> userProperties, String key, boolean def) { return doGet(userProperties != null ? userProperties.get(key) : null, def); } - private static boolean doGet(Object val, boolean def) { + private static boolean doGet(@Nullable Object val, boolean def) { if (val instanceof Boolean bool) { return bool; } else if (val != null) { diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/MojoException.java b/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/MojoException.java index 2d4b976cee..e15bf7f448 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/MojoException.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/MojoException.java @@ -19,6 +19,7 @@ package org.apache.maven.api.plugin; import org.apache.maven.api.annotations.Experimental; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.services.MavenException; /** @@ -29,15 +30,17 @@ @Experimental public class MojoException extends MavenException { + @Nullable protected Object source; + @Nullable protected String longMessage; /** * Constructs a new {@code MojoException} providing the source and a short and long message. * These messages are used to improve the message written at the end of Maven build. */ - public MojoException(Object source, String shortMessage, String longMessage) { + public MojoException(@Nullable Object source, String shortMessage, @Nullable String longMessage) { super(shortMessage); this.source = source; this.longMessage = longMessage; @@ -68,10 +71,12 @@ public MojoException(Throwable cause) { super(cause); } + @Nullable public String getLongMessage() { return longMessage; } + @Nullable public Object getSource() { return source; } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactCoordinatesFactoryRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactCoordinatesFactoryRequest.java index d2c3540f3c..5ff73d4139 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactCoordinatesFactoryRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactCoordinatesFactoryRequest.java @@ -26,6 +26,7 @@ import org.apache.maven.api.annotations.Immutable; import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.annotations.NotThreadSafe; +import org.apache.maven.api.annotations.Nullable; import static java.util.Objects.requireNonNull; @@ -38,23 +39,34 @@ @Immutable public interface ArtifactCoordinatesFactoryRequest extends Request<Session> { + @Nullable String getGroupId(); + @Nullable String getArtifactId(); + @Nullable String getVersion(); + @Nullable String getClassifier(); + @Nullable String getExtension(); + @Nullable String getType(); + @Nullable String getCoordinatesString(); @Nonnull static ArtifactCoordinatesFactoryRequest build( - @Nonnull Session session, String groupId, String artifactId, String version, String extension) { + @Nonnull Session session, + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String extension) { return ArtifactCoordinatesFactoryRequest.builder() .session(requireNonNull(session, "session")) .groupId(groupId) @@ -67,12 +79,12 @@ static ArtifactCoordinatesFactoryRequest build( @Nonnull static ArtifactCoordinatesFactoryRequest build( @Nonnull Session session, - String groupId, - String artifactId, - String version, - String classifier, - String extension, - String type) { + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String classifier, + @Nullable String extension, + @Nullable String type) { return ArtifactCoordinatesFactoryRequest.builder() .session(requireNonNull(session, "session")) .groupId(groupId) @@ -110,14 +122,31 @@ static ArtifactFactoryRequestBuilder builder() { @NotThreadSafe class ArtifactFactoryRequestBuilder { + @Nullable private Session session; + + @Nullable private RequestTrace trace; + + @Nullable private String groupId; + + @Nullable private String artifactId; + + @Nullable private String version; + + @Nullable private String classifier; + + @Nullable private String extension; + + @Nullable private String type; + + @Nullable private String coordinateString; ArtifactFactoryRequestBuilder() {} @@ -132,67 +161,88 @@ public ArtifactFactoryRequestBuilder trace(RequestTrace trace) { return this; } - public ArtifactFactoryRequestBuilder groupId(String groupId) { + public ArtifactFactoryRequestBuilder groupId(@Nullable String groupId) { this.groupId = groupId; return this; } - public ArtifactFactoryRequestBuilder artifactId(String artifactId) { + public ArtifactFactoryRequestBuilder artifactId(@Nullable String artifactId) { this.artifactId = artifactId; return this; } - public ArtifactFactoryRequestBuilder version(String version) { + public ArtifactFactoryRequestBuilder version(@Nullable String version) { this.version = version; return this; } - public ArtifactFactoryRequestBuilder classifier(String classifier) { + public ArtifactFactoryRequestBuilder classifier(@Nullable String classifier) { this.classifier = classifier; return this; } - public ArtifactFactoryRequestBuilder extension(String extension) { + public ArtifactFactoryRequestBuilder extension(@Nullable String extension) { this.extension = extension; return this; } - public ArtifactFactoryRequestBuilder type(String type) { + public ArtifactFactoryRequestBuilder type(@Nullable String type) { this.type = type; return this; } - public ArtifactFactoryRequestBuilder coordinateString(String coordinateString) { + public ArtifactFactoryRequestBuilder coordinateString(@Nullable String coordinateString) { this.coordinateString = coordinateString; return this; } public ArtifactCoordinatesFactoryRequest build() { return new DefaultArtifactFactoryRequestArtifact( - session, trace, groupId, artifactId, version, classifier, extension, type, coordinateString); + requireNonNull(session, "session cannot be null"), + trace, + groupId, + artifactId, + version, + classifier, + extension, + type, + coordinateString); } private static class DefaultArtifactFactoryRequestArtifact extends BaseRequest<Session> implements ArtifactCoordinatesFactoryRequest { + @Nullable private final String groupId; + + @Nullable private final String artifactId; + + @Nullable private final String version; + + @Nullable private final String classifier; + + @Nullable private final String extension; + + @Nullable private final String type; + + @Nullable private final String coordinatesString; @SuppressWarnings("checkstyle:ParameterNumber") DefaultArtifactFactoryRequestArtifact( @Nonnull Session session, - RequestTrace trace, - String groupId, - String artifactId, - String version, - String classifier, - String extension, - String type, - String coordinatesString) { + @Nullable RequestTrace trace, + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String classifier, + @Nullable String extension, + @Nullable String type, + @Nullable String coordinatesString) { super(session, trace); this.groupId = groupId; this.artifactId = artifactId; @@ -203,36 +253,43 @@ private static class DefaultArtifactFactoryRequestArtifact extends BaseRequest<S this.coordinatesString = coordinatesString; } + @Nullable @Override public String getGroupId() { return groupId; } + @Nullable @Override public String getArtifactId() { return artifactId; } + @Nullable @Override public String getVersion() { return version; } + @Nullable @Override public String getClassifier() { return classifier; } + @Nullable @Override public String getExtension() { return extension; } + @Nullable @Override public String getType() { return type; } + @Nullable @Override public String getCoordinatesString() { return coordinatesString; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactDeployerRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactDeployerRequest.java index 8d54d882c0..d0d3e19e89 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactDeployerRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactDeployerRequest.java @@ -67,10 +67,18 @@ static ArtifactDeployerRequest build( } class ArtifactDeployerRequestBuilder { + @Nullable Session session; + + @Nullable RequestTrace trace; + + @Nullable RemoteRepository repository; + + @Nullable Collection<ProducedArtifact> artifacts; + int retryFailedDeploymentCount; ArtifactDeployerRequestBuilder() {} @@ -106,7 +114,11 @@ public ArtifactDeployerRequestBuilder retryFailedDeploymentCount(int retryFailed @Nonnull public ArtifactDeployerRequest build() { return new DefaultArtifactDeployerRequest( - session, trace, repository, artifacts, retryFailedDeploymentCount); + requireNonNull(session, "session cannot be null"), + trace, + requireNonNull(repository, "repository cannot be null"), + requireNonNull(artifacts, "artifacts cannot be null"), + retryFailedDeploymentCount); } private static class DefaultArtifactDeployerRequest extends BaseRequest<Session> diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactFactoryRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactFactoryRequest.java index 0d97922374..9b87ee18e0 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactFactoryRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactFactoryRequest.java @@ -38,16 +38,22 @@ @Immutable public interface ArtifactFactoryRequest extends Request<Session> { + @Nullable String getGroupId(); + @Nullable String getArtifactId(); + @Nullable String getVersion(); + @Nullable String getClassifier(); + @Nullable String getExtension(); + @Nullable String getType(); static ArtifactFactoryRequest build( @@ -86,13 +92,28 @@ static ArtifactFactoryRequestBuilder builder() { @NotThreadSafe class ArtifactFactoryRequestBuilder { + @Nullable private Session session; + + @Nullable private RequestTrace trace; + + @Nullable private String groupId; + + @Nullable private String artifactId; + + @Nullable private String version; + + @Nullable private String classifier; + + @Nullable private String extension; + + @Nullable private String type; ArtifactFactoryRequestBuilder() {} @@ -139,28 +160,46 @@ public ArtifactFactoryRequestBuilder type(String type) { public ArtifactFactoryRequest build() { return new DefaultArtifactFactoryRequest( - session, trace, groupId, artifactId, version, classifier, extension, type); + requireNonNull(session, "session cannot be null"), + trace, + groupId, + artifactId, + version, + classifier, + extension, + type); } private static class DefaultArtifactFactoryRequest extends BaseRequest<Session> implements ArtifactFactoryRequest { + @Nullable private final String groupId; + + @Nullable private final String artifactId; + + @Nullable private final String version; + + @Nullable private final String classifier; + + @Nullable private final String extension; + + @Nullable private final String type; @SuppressWarnings("checkstyle:ParameterNumber") DefaultArtifactFactoryRequest( @Nonnull Session session, @Nullable RequestTrace trace, - String groupId, - String artifactId, - String version, - String classifier, - String extension, - String type) { + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String classifier, + @Nullable String extension, + @Nullable String type) { super(session, trace); this.groupId = groupId; this.artifactId = artifactId; @@ -170,31 +209,37 @@ private static class DefaultArtifactFactoryRequest extends BaseRequest<Session> this.type = type; } + @Nullable @Override public String getGroupId() { return groupId; } + @Nullable @Override public String getArtifactId() { return artifactId; } + @Nullable @Override public String getVersion() { return version; } + @Nullable @Override public String getClassifier() { return classifier; } + @Nullable @Override public String getExtension() { return extension; } + @Nullable @Override public String getType() { return type; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactInstallerRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactInstallerRequest.java index 6f5a57e0ea..aaf5251843 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactInstallerRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactInstallerRequest.java @@ -60,8 +60,12 @@ static ArtifactInstallerRequest build(Session session, Collection<ProducedArtifa @NotThreadSafe class ArtifactInstallerRequestBuilder { + @Nullable Session session; + + @Nullable RequestTrace trace; + Collection<ProducedArtifact> artifacts = Collections.emptyList(); ArtifactInstallerRequestBuilder() {} @@ -86,7 +90,8 @@ public ArtifactInstallerRequestBuilder artifacts(@Nullable Collection<ProducedAr @Nonnull public ArtifactInstallerRequest build() { - return new DefaultArtifactInstallerRequest(session, trace, artifacts); + return new DefaultArtifactInstallerRequest( + requireNonNull(session, "session cannot be null"), trace, artifacts); } static class DefaultArtifactInstallerRequest extends BaseRequest<Session> implements ArtifactInstallerRequest { diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverRequest.java index 7e832a95e4..893b9352c4 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverRequest.java @@ -73,9 +73,16 @@ static ArtifactResolverRequest build( @NotThreadSafe class ArtifactResolverRequestBuilder { + @Nullable Session session; + + @Nullable RequestTrace trace; + + @Nullable Collection<? extends ArtifactCoordinates> coordinates; + + @Nullable List<RemoteRepository> repositories; ArtifactResolverRequestBuilder() {} @@ -106,7 +113,11 @@ public ArtifactResolverRequestBuilder repositories(List<RemoteRepository> reposi @Nonnull public ArtifactResolverRequest build() { - return new DefaultArtifactResolverRequest(session, trace, coordinates, repositories); + return new DefaultArtifactResolverRequest( + requireNonNull(session, "session cannot be null"), + trace, + requireNonNull(coordinates, "coordinates cannot be null"), + repositories); } private static class DefaultArtifactResolverRequest extends BaseRequest<Session> @@ -121,7 +132,7 @@ private static class DefaultArtifactResolverRequest extends BaseRequest<Session> @Nonnull Session session, @Nullable RequestTrace trace, @Nonnull Collection<? extends ArtifactCoordinates> coordinates, - @Nonnull List<RemoteRepository> repositories) { + @Nullable List<RemoteRepository> repositories) { super(session, trace); this.coordinates = List.copyOf(requireNonNull(coordinates, "coordinates cannot be null")); this.repositories = validate(repositories); diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverResult.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverResult.java index 5f76c2c7bf..b2ca6bc217 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverResult.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ArtifactResolverResult.java @@ -74,6 +74,7 @@ public interface ArtifactResolverResult extends Result<ArtifactResolverRequest> * @param coordinates The {@link ArtifactCoordinates} identifying the artifact. * @return The corresponding {@link ResultItem}, or {@code null} if no result exists. */ + @Nullable default ResultItem getResult(ArtifactCoordinates coordinates) { return getResults().get(coordinates); } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/BaseRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/BaseRequest.java index b5e338466a..748a48e599 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/BaseRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/BaseRequest.java @@ -21,6 +21,7 @@ import org.apache.maven.api.ProtoSession; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.annotations.Nullable; import static java.util.Objects.requireNonNull; @@ -33,13 +34,15 @@ abstract class BaseRequest<S extends ProtoSession> implements Request<S> { private final S session; + + @Nullable private final RequestTrace trace; protected BaseRequest(@Nonnull S session) { this(session, null); } - protected BaseRequest(@Nonnull S session, RequestTrace trace) { + protected BaseRequest(@Nonnull S session, @Nullable RequestTrace trace) { this.session = requireNonNull(session, "session cannot be null"); this.trace = trace; } @@ -50,6 +53,7 @@ public S getSession() { return session; } + @Nullable @Override public RequestTrace getTrace() { return trace; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCoordinatesFactoryRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCoordinatesFactoryRequest.java index c0314b2078..4f46d9bfe3 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCoordinatesFactoryRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCoordinatesFactoryRequest.java @@ -43,6 +43,7 @@ @Immutable public interface DependencyCoordinatesFactoryRequest extends ArtifactCoordinatesFactoryRequest { + @Nullable String getScope(); boolean isOptional(); @@ -53,12 +54,12 @@ public interface DependencyCoordinatesFactoryRequest extends ArtifactCoordinates @Nonnull static DependencyCoordinatesFactoryRequest build( @Nonnull Session session, - String groupId, - String artifactId, - String version, - String classifier, - String extension, - String type) { + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String classifier, + @Nullable String extension, + @Nullable String type) { return DependencyCoordinatesFactoryRequest.builder() .session(requireNonNull(session, "session cannot be null")) .groupId(groupId) @@ -106,16 +107,36 @@ static DependencyCoordinatesFactoryRequestBuilder builder() { @NotThreadSafe class DependencyCoordinatesFactoryRequestBuilder { + @Nullable private Session session; + + @Nullable private RequestTrace trace; + + @Nullable private String groupId; + + @Nullable private String artifactId; + + @Nullable private String version; + + @Nullable private String classifier; + + @Nullable private String extension; + + @Nullable private String type; + + @Nullable private String coordinateString; + + @Nullable private String scope; + private boolean optional; private Collection<Exclusion> exclusions = Collections.emptyList(); @@ -131,42 +152,42 @@ public DependencyCoordinatesFactoryRequestBuilder trace(RequestTrace trace) { return this; } - public DependencyCoordinatesFactoryRequestBuilder groupId(String groupId) { + public DependencyCoordinatesFactoryRequestBuilder groupId(@Nullable String groupId) { this.groupId = groupId; return this; } - public DependencyCoordinatesFactoryRequestBuilder artifactId(String artifactId) { + public DependencyCoordinatesFactoryRequestBuilder artifactId(@Nullable String artifactId) { this.artifactId = artifactId; return this; } - public DependencyCoordinatesFactoryRequestBuilder version(String version) { + public DependencyCoordinatesFactoryRequestBuilder version(@Nullable String version) { this.version = version; return this; } - public DependencyCoordinatesFactoryRequestBuilder classifier(String classifier) { + public DependencyCoordinatesFactoryRequestBuilder classifier(@Nullable String classifier) { this.classifier = classifier; return this; } - public DependencyCoordinatesFactoryRequestBuilder extension(String extension) { + public DependencyCoordinatesFactoryRequestBuilder extension(@Nullable String extension) { this.extension = extension; return this; } - public DependencyCoordinatesFactoryRequestBuilder type(String type) { + public DependencyCoordinatesFactoryRequestBuilder type(@Nullable String type) { this.type = type; return this; } - public DependencyCoordinatesFactoryRequestBuilder coordinateString(String coordinateString) { + public DependencyCoordinatesFactoryRequestBuilder coordinateString(@Nullable String coordinateString) { this.coordinateString = coordinateString; return this; } - public DependencyCoordinatesFactoryRequestBuilder scope(String scope) { + public DependencyCoordinatesFactoryRequestBuilder scope(@Nullable String scope) { this.scope = scope; return this; } @@ -198,7 +219,7 @@ public DependencyCoordinatesFactoryRequestBuilder exclusion(Exclusion exclusion) public DependencyCoordinatesFactoryRequest build() { return new DefaultDependencyCoordinatesFactoryRequest( - session, + requireNonNull(session, "session cannot be null"), trace, groupId, artifactId, @@ -214,14 +235,30 @@ public DependencyCoordinatesFactoryRequest build() { private static class DefaultDependencyCoordinatesFactoryRequest extends BaseRequest<Session> implements DependencyCoordinatesFactoryRequest { + @Nullable private final String groupId; + + @Nullable private final String artifactId; + + @Nullable private final String version; + + @Nullable private final String classifier; + + @Nullable private final String extension; + + @Nullable private final String type; + + @Nullable private final String coordinateString; + + @Nullable private final String scope; + private final boolean optional; private final Collection<Exclusion> exclusions; @@ -229,14 +266,14 @@ private static class DefaultDependencyCoordinatesFactoryRequest extends BaseRequ private DefaultDependencyCoordinatesFactoryRequest( @Nonnull Session session, @Nullable RequestTrace trace, - String groupId, - String artifactId, - String version, - String classifier, - String extension, - String type, - String coordinateString, - String scope, + @Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String classifier, + @Nullable String extension, + @Nullable String type, + @Nullable String coordinateString, + @Nullable String scope, boolean optional, Collection<Exclusion> exclusions) { super(session, trace); @@ -252,41 +289,49 @@ private DefaultDependencyCoordinatesFactoryRequest( this.exclusions = exclusions; } + @Nullable @Override public String getGroupId() { return groupId; } + @Nullable @Override public String getArtifactId() { return artifactId; } + @Nullable @Override public String getVersion() { return version; } + @Nullable @Override public String getClassifier() { return classifier; } + @Nullable @Override public String getExtension() { return extension; } + @Nullable @Override public String getType() { return type; } + @Nullable @Override public String getCoordinatesString() { return coordinateString; } + @Nullable @Override public String getScope() { return scope; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java index 5be250824d..2bb516b24b 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java @@ -191,18 +191,38 @@ static DependencyResolverRequest build( @NotThreadSafe class DependencyResolverRequestBuilder { + @Nullable Session session; + + @Nullable RequestTrace trace; + + @Nullable RequestType requestType; + + @Nullable Project project; + + @Nullable Artifact rootArtifact; + + @Nullable DependencyCoordinates root; + List<DependencyCoordinates> dependencies = Collections.emptyList(); List<DependencyCoordinates> managedDependencies = Collections.emptyList(); boolean verbose; + + @Nullable PathScope pathScope; + + @Nullable Predicate<PathType> pathTypeFilter; + + @Nullable Version targetVersion; + + @Nullable List<RemoteRepository> repositories; DependencyResolverRequestBuilder() {} @@ -388,16 +408,16 @@ public DependencyResolverRequestBuilder repositories(@Nonnull List<RemoteReposit @Nonnull public DependencyResolverRequest build() { return new DefaultDependencyResolverRequest( - session, + requireNonNull(session, "session cannot be null"), trace, - requestType, + requireNonNull(requestType, "requestType cannot be null"), project, rootArtifact, root, dependencies, managedDependencies, verbose, - pathScope, + requireNonNull(pathScope, "pathScope cannot be null"), pathTypeFilter, targetVersion, repositories); @@ -431,15 +451,26 @@ public String toString() { private static final Predicate<PathType> DEFAULT_FILTER = new AlwaysTrueFilter(); private final RequestType requestType; + + @Nullable private final Project project; + + @Nullable private final Artifact rootArtifact; + + @Nullable private final DependencyCoordinates root; + private final Collection<DependencyCoordinates> dependencies; private final Collection<DependencyCoordinates> managedDependencies; private final boolean verbose; private final PathScope pathScope; private final Predicate<PathType> pathTypeFilter; + + @Nullable private final Version targetVersion; + + @Nullable private final List<RemoteRepository> repositories; /** @@ -533,11 +564,13 @@ public Predicate<PathType> getPathTypeFilter() { return pathTypeFilter; } + @Nullable @Override public Version getTargetVersion() { return targetVersion; } + @Nullable @Override public List<RemoteRepository> getRepositories() { return repositories; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/MavenBuilderException.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/MavenBuilderException.java index a39cb9aa1a..97b83bf54f 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/MavenBuilderException.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/MavenBuilderException.java @@ -53,7 +53,7 @@ public MavenBuilderException(String message, Throwable cause) { * @param problems the collection of problems associated with this exception */ public MavenBuilderException(String message, ProblemCollector<BuilderProblem> problems) { - super(buildMessage(message, problems), null); + super(buildMessage(message, problems), (Throwable) null); this.problems = problems; } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/MavenException.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/MavenException.java index cdd9ced96c..a5f42e9417 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/MavenException.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/MavenException.java @@ -19,6 +19,7 @@ package org.apache.maven.api.services; import org.apache.maven.api.annotations.Experimental; +import org.apache.maven.api.annotations.Nullable; /** * Base class for all maven exceptions. @@ -30,15 +31,15 @@ public class MavenException extends RuntimeException { public MavenException() {} - public MavenException(String message) { + public MavenException(@Nullable String message) { super(message); } - public MavenException(String message, Throwable cause) { + public MavenException(@Nullable String message, @Nullable Throwable cause) { super(message, cause); } - public MavenException(Throwable cause) { + public MavenException(@Nullable Throwable cause) { super(cause); } } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java index 826ffe8fc4..53bf1592cd 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java @@ -130,7 +130,7 @@ enum RepositoryMerging { @Nonnull Map<String, String> getUserProperties(); - @Nonnull + @Nullable RepositoryMerging getRepositoryMerging(); @Nullable @@ -171,19 +171,43 @@ static ModelBuilderRequestBuilder builder(ModelBuilderRequest request) { @NotThreadSafe class ModelBuilderRequestBuilder { + @Nullable Session session; + + @Nullable RequestTrace trace; + + @Nullable RequestType requestType; + boolean locationTracking; boolean recursive; + + @Nullable ModelSource source; + + @Nullable Collection<Profile> profiles; + + @Nullable List<String> activeProfileIds; + + @Nullable List<String> inactiveProfileIds; + + @Nullable Map<String, String> systemProperties; + + @Nullable Map<String, String> userProperties; + + @Nullable RepositoryMerging repositoryMerging; + + @Nullable List<RemoteRepository> repositories; + + @Nullable ModelTransformer lifecycleBindingsInjector; ModelBuilderRequestBuilder() {} @@ -277,12 +301,12 @@ public ModelBuilderRequestBuilder lifecycleBindingsInjector(ModelTransformer lif public ModelBuilderRequest build() { return new DefaultModelBuilderRequest( - session, + requireNonNull(session, "session cannot be null"), trace, - requestType, + requireNonNull(requestType, "requestType cannot be null"), locationTracking, recursive, - source, + requireNonNull(source, "source cannot be null"), profiles, activeProfileIds, inactiveProfileIds, @@ -297,14 +321,22 @@ private static class DefaultModelBuilderRequest extends BaseRequest<Session> imp private final RequestType requestType; private final boolean locationTracking; private final boolean recursive; + private final ModelSource source; + private final Collection<Profile> profiles; private final List<String> activeProfileIds; private final List<String> inactiveProfileIds; private final Map<String, String> systemProperties; private final Map<String, String> userProperties; + + @Nullable private final RepositoryMerging repositoryMerging; + + @Nullable private final List<RemoteRepository> repositories; + + @Nullable private final ModelTransformer lifecycleBindingsInjector; @SuppressWarnings("checkstyle:ParameterNumber") @@ -315,15 +347,16 @@ private static class DefaultModelBuilderRequest extends BaseRequest<Session> imp boolean locationTracking, boolean recursive, @Nonnull ModelSource source, - Collection<Profile> profiles, - List<String> activeProfileIds, - List<String> inactiveProfileIds, - Map<String, String> systemProperties, - Map<String, String> userProperties, - RepositoryMerging repositoryMerging, - List<RemoteRepository> repositories, - ModelTransformer lifecycleBindingsInjector) { + @Nullable Collection<Profile> profiles, + @Nullable List<String> activeProfileIds, + @Nullable List<String> inactiveProfileIds, + @Nullable Map<String, String> systemProperties, + @Nullable Map<String, String> userProperties, + @Nullable RepositoryMerging repositoryMerging, + @Nullable List<RemoteRepository> repositories, + @Nullable ModelTransformer lifecycleBindingsInjector) { super(session, trace); + Session s = getSession(); this.requestType = requireNonNull(requestType, "requestType cannot be null"); this.locationTracking = locationTracking; this.recursive = recursive; @@ -332,8 +365,8 @@ private static class DefaultModelBuilderRequest extends BaseRequest<Session> imp this.activeProfileIds = activeProfileIds != null ? List.copyOf(activeProfileIds) : List.of(); this.inactiveProfileIds = inactiveProfileIds != null ? List.copyOf(inactiveProfileIds) : List.of(); this.systemProperties = - systemProperties != null ? Map.copyOf(systemProperties) : session.getSystemProperties(); - this.userProperties = userProperties != null ? Map.copyOf(userProperties) : session.getUserProperties(); + systemProperties != null ? Map.copyOf(systemProperties) : s.getSystemProperties(); + this.userProperties = userProperties != null ? Map.copyOf(userProperties) : s.getUserProperties(); this.repositoryMerging = repositoryMerging; this.repositories = repositories != null ? List.copyOf(validate(repositories)) : null; this.lifecycleBindingsInjector = lifecycleBindingsInjector; @@ -385,16 +418,19 @@ public Map<String, String> getUserProperties() { return userProperties; } + @Nullable @Override public RepositoryMerging getRepositoryMerging() { return repositoryMerging; } + @Nullable @Override public List<RemoteRepository> getRepositories() { return repositories; } + @Nullable @Override public ModelTransformer getLifecycleBindingsInjector() { return lifecycleBindingsInjector; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelProblemCollector.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelProblemCollector.java index 66c1fcc31e..9acffca804 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelProblemCollector.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelProblemCollector.java @@ -18,6 +18,7 @@ */ package org.apache.maven.api.services; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.model.InputLocation; import org.apache.maven.api.model.Model; @@ -59,8 +60,8 @@ void add( BuilderProblem.Severity severity, ModelProblem.Version version, String message, - InputLocation location, - Exception exception); + @Nullable InputLocation location, + @Nullable Exception exception); default void add(ModelProblem problem) { getProblemCollector().reportProblem(problem); diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/PathMatcherFactory.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/PathMatcherFactory.java index 9f83e2e0f8..3d7b7113c8 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/PathMatcherFactory.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/PathMatcherFactory.java @@ -26,6 +26,7 @@ import org.apache.maven.api.Service; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.annotations.Nullable; /** * Service for creating {@link PathMatcher} objects that can be used to filter files @@ -66,8 +67,8 @@ public interface PathMatcherFactory extends Service { @Nonnull PathMatcher createPathMatcher( @Nonnull Path baseDirectory, - Collection<String> includes, - Collection<String> excludes, + @Nullable Collection<String> includes, + @Nullable Collection<String> excludes, boolean useDefaultExcludes); /** diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectBuilderRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectBuilderRequest.java index 307ee19559..b15263ce1c 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectBuilderRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectBuilderRequest.java @@ -146,13 +146,23 @@ static ProjectBuilderRequestBuilder builder() { */ @NotThreadSafe class ProjectBuilderRequestBuilder { + @Nullable Session session; + + @Nullable RequestTrace trace; + + @Nullable Path path; + + @Nullable Source source; + boolean allowStubModel; boolean recursive; boolean processPlugins = true; + + @Nullable List<RemoteRepository> repositories; ProjectBuilderRequestBuilder() {} @@ -237,16 +247,29 @@ public ProjectBuilderRequestBuilder repositories(List<RemoteRepository> reposito */ public ProjectBuilderRequest build() { return new DefaultProjectBuilderRequest( - session, trace, path, source, allowStubModel, recursive, processPlugins, repositories); + requireNonNull(session, "session cannot be null"), + trace, + path, + source, + allowStubModel, + recursive, + processPlugins, + repositories); } private static class DefaultProjectBuilderRequest extends BaseRequest<Session> implements ProjectBuilderRequest { + @Nullable private final Path path; + + @Nullable private final Source source; + private final boolean allowStubModel; private final boolean recursive; private final boolean processPlugins; + + @Nullable private final List<RemoteRepository> repositories; @SuppressWarnings("checkstyle:ParameterNumber") @@ -295,6 +318,7 @@ public boolean isProcessPlugins() { return processPlugins; } + @Nullable @Override public List<RemoteRepository> getRepositories() { return repositories; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/RepositoryAwareRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/RepositoryAwareRequest.java index f948ecdea4..845399582f 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/RepositoryAwareRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/RepositoryAwareRequest.java @@ -97,7 +97,8 @@ public interface RepositoryAwareRequest extends Request<Session> { * @throws IllegalArgumentException if the list contains duplicate repositories * @throws IllegalArgumentException if the list contains null repository entries */ - default List<RemoteRepository> validate(List<RemoteRepository> repositories) { + @Nullable + default List<RemoteRepository> validate(@Nullable List<RemoteRepository> repositories) { if (repositories == null) { return null; } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilder.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilder.java index 000ebb8837..086d5a0b25 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilder.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilder.java @@ -53,7 +53,7 @@ public interface SettingsBuilder extends Service { @Nonnull default SettingsBuilderResult build( @Nonnull Session session, @Nonnull Source installationSettingsSource, @Nonnull Source userSettingsSource) { - return build(session, installationSettingsSource, null, userSettingsSource); + return build(SettingsBuilderRequest.build(session, installationSettingsSource, null, userSettingsSource)); } /** @@ -65,7 +65,7 @@ default SettingsBuilderResult build( @Nonnull default SettingsBuilderResult build( @Nonnull Session session, @Nonnull Path installationSettingsPath, @Nonnull Path userSettingsPath) { - return build(session, installationSettingsPath, null, userSettingsPath); + return build(SettingsBuilderRequest.build(session, installationSettingsPath, null, userSettingsPath)); } /** diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java index 1ab8a9a15b..7a23421d70 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java @@ -130,11 +130,22 @@ static SettingsBuilderRequestBuilder builder() { @NotThreadSafe class SettingsBuilderRequestBuilder { + @Nullable ProtoSession session; + + @Nullable RequestTrace trace; + + @Nullable Source installationSettingsSource; + + @Nullable Source projectSettingsSource; + + @Nullable Source userSettingsSource; + + @Nullable UnaryOperator<String> interpolationSource; public SettingsBuilderRequestBuilder session(ProtoSession session) { @@ -147,29 +158,29 @@ public SettingsBuilderRequestBuilder trace(RequestTrace trace) { return this; } - public SettingsBuilderRequestBuilder installationSettingsSource(Source installationSettingsSource) { + public SettingsBuilderRequestBuilder installationSettingsSource(@Nullable Source installationSettingsSource) { this.installationSettingsSource = installationSettingsSource; return this; } - public SettingsBuilderRequestBuilder projectSettingsSource(Source projectSettingsSource) { + public SettingsBuilderRequestBuilder projectSettingsSource(@Nullable Source projectSettingsSource) { this.projectSettingsSource = projectSettingsSource; return this; } - public SettingsBuilderRequestBuilder userSettingsSource(Source userSettingsSource) { + public SettingsBuilderRequestBuilder userSettingsSource(@Nullable Source userSettingsSource) { this.userSettingsSource = userSettingsSource; return this; } - public SettingsBuilderRequestBuilder interpolationSource(UnaryOperator<String> interpolationSource) { + public SettingsBuilderRequestBuilder interpolationSource(@Nullable UnaryOperator<String> interpolationSource) { this.interpolationSource = interpolationSource; return this; } public SettingsBuilderRequest build() { return new DefaultSettingsBuilderRequest( - session, + requireNonNull(session, "session cannot be null"), trace, installationSettingsSource, projectSettingsSource, @@ -179,9 +190,16 @@ public SettingsBuilderRequest build() { private static class DefaultSettingsBuilderRequest extends BaseRequest<ProtoSession> implements SettingsBuilderRequest { + @Nullable private final Source installationSettingsSource; + + @Nullable private final Source projectSettingsSource; + + @Nullable private final Source userSettingsSource; + + @Nullable private final UnaryOperator<String> interpolationSource; @SuppressWarnings("checkstyle:ParameterNumber") diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/Sources.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/Sources.java index 73d8978424..77003d0004 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/Sources.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/Sources.java @@ -109,7 +109,7 @@ static class PathSource implements Source { * @param path the filesystem path to the source content * @throws NullPointerException if path is null */ - PathSource(Path path) { + PathSource(@Nonnull Path path) { this(path, null); } @@ -120,7 +120,7 @@ static class PathSource implements Source { * @param location the logical location of the source, used for reporting purposes. * If null, the path string representation is used */ - protected PathSource(Path path, String location) { + protected PathSource(@Nonnull Path path, @Nullable String location) { this.path = requireNonNull(path, "path").normalize(); this.location = location != null ? location : this.path.toString(); } @@ -173,12 +173,13 @@ static class ResolvedPathSource extends PathSource implements ModelSource { @Nullable private final String modelId; - ResolvedPathSource(Path path, String location, String modelId) { + ResolvedPathSource(@Nonnull Path path, @Nonnull String location, @Nullable String modelId) { super(path, location); this.modelId = modelId; } @Override + @Nullable public Path getPath() { return null; } @@ -190,6 +191,7 @@ public String getModelId() { } @Override + @Nullable public Source resolve(String relative) { return null; } @@ -238,7 +240,11 @@ public Source resolve(@Nonnull String relative) { @Nullable public ModelSource resolve(@Nonnull ModelLocator locator, @Nonnull String relative) { String norm = relative.replace('\\', File.separatorChar).replace('/', File.separatorChar); - Path path = getPath().getParent().resolve(norm); + Path parent = getPath().getParent(); + if (parent == null) { + return null; + } + Path path = parent.resolve(norm); Path relatedPom = locator.locateExistingPom(path); if (relatedPom != null) { return new BuildPathSource(relatedPom); diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainManager.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainManager.java index b867cd4f08..888020c872 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainManager.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainManager.java @@ -27,6 +27,7 @@ import org.apache.maven.api.Toolchain; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.annotations.Nullable; /** * Service interface for managing Maven toolchains, which provide abstraction for different @@ -51,7 +52,7 @@ public interface ToolchainManager extends Service { * @throws ToolchainManagerException if toolchain retrieval fails */ @Nonnull - List<Toolchain> getToolchains(@Nonnull Session session, String type, Map<String, String> requirements); + List<Toolchain> getToolchains(@Nonnull Session session, String type, @Nullable Map<String, String> requirements); /** * Retrieves all toolchains of the specified type without additional requirements. diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainsBuilderRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainsBuilderRequest.java index 0257ae6760..d45d285440 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainsBuilderRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ToolchainsBuilderRequest.java @@ -91,9 +91,16 @@ static ToolchainsBuilderRequestBuilder builder() { @NotThreadSafe class ToolchainsBuilderRequestBuilder { + @Nullable ProtoSession session; + + @Nullable RequestTrace trace; + + @Nullable Source installationToolchainsSource; + + @Nullable Source userToolchainsSource; public ToolchainsBuilderRequestBuilder session(ProtoSession session) { @@ -106,24 +113,31 @@ public ToolchainsBuilderRequestBuilder trace(RequestTrace trace) { return this; } - public ToolchainsBuilderRequestBuilder installationToolchainsSource(Source installationToolchainsSource) { + public ToolchainsBuilderRequestBuilder installationToolchainsSource( + @Nullable Source installationToolchainsSource) { this.installationToolchainsSource = installationToolchainsSource; return this; } - public ToolchainsBuilderRequestBuilder userToolchainsSource(Source userToolchainsSource) { + public ToolchainsBuilderRequestBuilder userToolchainsSource(@Nullable Source userToolchainsSource) { this.userToolchainsSource = userToolchainsSource; return this; } public ToolchainsBuilderRequest build() { return new ToolchainsBuilderRequestBuilder.DefaultToolchainsBuilderRequest( - session, trace, installationToolchainsSource, userToolchainsSource); + requireNonNull(session, "session cannot be null"), + trace, + installationToolchainsSource, + userToolchainsSource); } private static class DefaultToolchainsBuilderRequest extends BaseRequest<ProtoSession> implements ToolchainsBuilderRequest { + @Nullable private final Source installationToolchainsSource; + + @Nullable private final Source userToolchainsSource; @SuppressWarnings("checkstyle:ParameterNumber") diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/VersionRangeResolverRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/VersionRangeResolverRequest.java index 50de8e9a80..207f93cfcc 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/VersionRangeResolverRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/VersionRangeResolverRequest.java @@ -148,10 +148,18 @@ static VersionResolverRequestBuilder builder() { */ @NotThreadSafe class VersionResolverRequestBuilder { + @Nullable Session session; + + @Nullable RequestTrace trace; + + @Nullable ArtifactCoordinates artifactCoordinates; + + @Nullable List<RemoteRepository> repositories; + Nature nature = Nature.RELEASE_OR_SNAPSHOT; /** @@ -194,7 +202,7 @@ public VersionResolverRequestBuilder artifactCoordinates(ArtifactCoordinates art * @param nature the repository nature, or {@code null} to use the default * @return this builder, never {@code null} */ - public VersionResolverRequestBuilder nature(Nature nature) { + public VersionResolverRequestBuilder nature(@Nullable Nature nature) { this.nature = Objects.requireNonNullElse(nature, Nature.RELEASE_OR_SNAPSHOT); return this; } @@ -205,7 +213,7 @@ public VersionResolverRequestBuilder nature(Nature nature) { * @param repositories the repositories, or {@code null} to use the session's repositories * @return this builder, never {@code null} */ - public VersionResolverRequestBuilder repositories(List<RemoteRepository> repositories) { + public VersionResolverRequestBuilder repositories(@Nullable List<RemoteRepository> repositories) { this.repositories = repositories; return this; } @@ -216,13 +224,21 @@ public VersionResolverRequestBuilder repositories(List<RemoteRepository> reposit * @return the version range resolver request, never {@code null} */ public VersionRangeResolverRequest build() { - return new DefaultVersionResolverRequest(session, trace, artifactCoordinates, repositories, nature); + return new DefaultVersionResolverRequest( + requireNonNull(session, "session cannot be null"), + trace, + requireNonNull(artifactCoordinates, "artifactCoordinates cannot be null"), + repositories, + nature); } private static class DefaultVersionResolverRequest extends BaseRequest<Session> implements VersionRangeResolverRequest { private final ArtifactCoordinates artifactCoordinates; + + @Nullable private final List<RemoteRepository> repositories; + private final Nature nature; @SuppressWarnings("checkstyle:ParameterNumber") diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/VersionResolverRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/VersionResolverRequest.java index b510dcc2de..c44e91e76a 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/VersionResolverRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/VersionResolverRequest.java @@ -68,9 +68,16 @@ static VersionResolverRequestBuilder builder() { @NotThreadSafe class VersionResolverRequestBuilder { + @Nullable Session session; + + @Nullable RequestTrace trace; + + @Nullable ArtifactCoordinates artifactCoordinates; + + @Nullable List<RemoteRepository> repositories; public VersionResolverRequestBuilder session(Session session) { @@ -88,18 +95,24 @@ public VersionResolverRequestBuilder artifactCoordinates(ArtifactCoordinates art return this; } - public VersionResolverRequestBuilder repositories(List<RemoteRepository> repositories) { + public VersionResolverRequestBuilder repositories(@Nullable List<RemoteRepository> repositories) { this.repositories = repositories; return this; } public VersionResolverRequest build() { - return new DefaultVersionResolverRequest(session, trace, artifactCoordinates, repositories); + return new DefaultVersionResolverRequest( + requireNonNull(session, "session cannot be null"), + trace, + requireNonNull(artifactCoordinates, "artifactCoordinates cannot be null"), + repositories); } private static class DefaultVersionResolverRequest extends BaseRequest<Session> implements VersionResolverRequest { private final ArtifactCoordinates artifactCoordinates; + + @Nullable private final List<RemoteRepository> repositories; @SuppressWarnings("checkstyle:ParameterNumber") @@ -109,7 +122,7 @@ private static class DefaultVersionResolverRequest extends BaseRequest<Session> @Nonnull ArtifactCoordinates artifactCoordinates, @Nullable List<RemoteRepository> repositories) { super(session, trace); - this.artifactCoordinates = artifactCoordinates; + this.artifactCoordinates = requireNonNull(artifactCoordinates, "artifactCoordinates cannot be null"); this.repositories = validate(repositories); } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/xml/XmlReaderRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/xml/XmlReaderRequest.java index 41733eb08b..7aa8da1446 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/xml/XmlReaderRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/xml/XmlReaderRequest.java @@ -85,15 +85,32 @@ static XmlReaderRequestBuilder builder() { @NotThreadSafe class XmlReaderRequestBuilder { + @Nullable Path path; + + @Nullable Path rootDirectory; + + @Nullable URL url; + + @Nullable InputStream inputStream; + + @Nullable Reader reader; + + @Nullable Transformer transformer; + boolean strict; + + @Nullable String modelId; + + @Nullable String location; + boolean addDefaultEntities = true; public XmlReaderRequestBuilder path(Path path) { @@ -161,28 +178,45 @@ public XmlReaderRequest build() { } private static class DefaultXmlReaderRequest implements XmlReaderRequest { + @Nullable final Path path; + + @Nullable final Path rootDirectory; + + @Nullable final URL url; + + @Nullable final InputStream inputStream; + + @Nullable final Reader reader; + + @Nullable final Transformer transformer; + final boolean strict; + + @Nullable final String modelId; + + @Nullable final String location; + final boolean addDefaultEntities; @SuppressWarnings("checkstyle:ParameterNumber") DefaultXmlReaderRequest( - Path path, - Path rootDirectory, - URL url, - InputStream inputStream, - Reader reader, - Transformer transformer, + @Nullable Path path, + @Nullable Path rootDirectory, + @Nullable URL url, + @Nullable InputStream inputStream, + @Nullable Reader reader, + @Nullable Transformer transformer, boolean strict, - String modelId, - String location, + @Nullable String modelId, + @Nullable String location, boolean addDefaultEntities) { this.path = path; this.rootDirectory = rootDirectory; @@ -196,31 +230,37 @@ private static class DefaultXmlReaderRequest implements XmlReaderRequest { this.addDefaultEntities = addDefaultEntities; } + @Nullable @Override public Path getPath() { return path; } + @Nullable @Override public Path getRootDirectory() { return rootDirectory; } + @Nullable @Override public URL getURL() { return url; } + @Nullable @Override public InputStream getInputStream() { return inputStream; } + @Nullable @Override public Reader getReader() { return reader; } + @Nullable @Override public Transformer getTransformer() { return transformer; @@ -231,11 +271,13 @@ public boolean isStrict() { return strict; } + @Nullable @Override public String getModelId() { return modelId; } + @Nullable @Override public String getLocation() { return location; diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/xml/XmlWriterRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/xml/XmlWriterRequest.java index 46ee89c8cf..e3c6bdb1b2 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/xml/XmlWriterRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/xml/XmlWriterRequest.java @@ -27,6 +27,8 @@ import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.annotations.Nullable; +import static java.util.Objects.requireNonNull; + /** * An XML writer request. * @@ -56,10 +58,19 @@ static <T> XmlWriterRequestBuilder<T> builder() { } class XmlWriterRequestBuilder<T> { + @Nullable Path path; + + @Nullable OutputStream outputStream; + + @Nullable Writer writer; + + @Nullable T content; + + @Nullable Function<Object, String> inputLocationFormatter; public XmlWriterRequestBuilder<T> path(Path path) { @@ -88,22 +99,35 @@ public XmlWriterRequestBuilder<T> inputLocationFormatter(Function<Object, String } public XmlWriterRequest<T> build() { - return new DefaultXmlWriterRequest<>(path, outputStream, writer, content, inputLocationFormatter); + return new DefaultXmlWriterRequest<>( + path, + outputStream, + writer, + requireNonNull(content, "content cannot be null"), + inputLocationFormatter); } private static class DefaultXmlWriterRequest<T> implements XmlWriterRequest<T> { + @Nullable final Path path; + + @Nullable final OutputStream outputStream; + + @Nullable final Writer writer; + final T content; + + @Nullable final Function<Object, String> inputLocationFormatter; DefaultXmlWriterRequest( - Path path, - OutputStream outputStream, - Writer writer, - T content, - Function<Object, String> inputLocationFormatter) { + @Nullable Path path, + @Nullable OutputStream outputStream, + @Nullable Writer writer, + @Nonnull T content, + @Nullable Function<Object, String> inputLocationFormatter) { this.path = path; this.outputStream = outputStream; this.writer = writer; @@ -111,26 +135,31 @@ private static class DefaultXmlWriterRequest<T> implements XmlWriterRequest<T> { this.inputLocationFormatter = inputLocationFormatter; } + @Nullable @Override public Path getPath() { return path; } + @Nullable @Override public OutputStream getOutputStream() { return outputStream; } + @Nullable @Override public Writer getWriter() { return writer; } + @Nonnull @Override public T getContent() { return content; } + @Nullable @Override public Function<Object, String> getInputLocationFormatter() { return inputLocationFormatter; diff --git a/api/maven-api-model/src/main/java/org/apache/maven/api/model/ModelObjectProcessor.java b/api/maven-api-model/src/main/java/org/apache/maven/api/model/ModelObjectProcessor.java index f1030709c0..eb9527f7d3 100644 --- a/api/maven-api-model/src/main/java/org/apache/maven/api/model/ModelObjectProcessor.java +++ b/api/maven-api-model/src/main/java/org/apache/maven/api/model/ModelObjectProcessor.java @@ -84,9 +84,12 @@ class ProcessorHolder { ModelObjectProcessor processor = ProcessorHolder.CACHED_PROCESSOR.get(); if (processor == null) { - processor = loadProcessor(); - ProcessorHolder.CACHED_PROCESSOR.compareAndSet(null, processor); + ModelObjectProcessor newProcessor = loadProcessor(); + ProcessorHolder.CACHED_PROCESSOR.compareAndSet(null, newProcessor); processor = ProcessorHolder.CACHED_PROCESSOR.get(); + if (processor == null) { + processor = newProcessor; + } } return processor.process(object); } diff --git a/api/maven-api-model/src/main/mdo/maven.mdo b/api/maven-api-model/src/main/mdo/maven.mdo index 74aff7785e..1ff0be615d 100644 --- a/api/maven-api-model/src/main/mdo/maven.mdo +++ b/api/maven-api-model/src/main/mdo/maven.mdo @@ -498,6 +498,7 @@ * @return The base directory for the corresponding project or {@code null} if this model does not belong to a local * project (e.g. describes the metadata of some artifact from the repository). */ + @Nullable public Path getProjectDirectory() { return (pomFile != null) ? pomFile.getParent() : null; } @@ -707,7 +708,7 @@ <version>4.1.0+</version> <code> <![CDATA[ - volatile Map<String, Plugin> pluginMap; + @Nullable volatile Map<String, Plugin> pluginMap; /** * @return a Map of plugins field with {@code Plugins#getKey()} as key @@ -1371,7 +1372,7 @@ <version>4.0.0+</version> <code> <![CDATA[ - private volatile String managementKey; + @Nullable private volatile String managementKey; /** * @return the management key as {@code groupId:artifactId:type[:classifier]} @@ -2285,6 +2286,7 @@ * @deprecated this was unused and has no replacement, this method returns {@code null} now. */ @Deprecated(since = "4.0.0") + @Nullable public String getMergeId() { return null; } @@ -2755,7 +2757,7 @@ * @param artifactId the artifact ID of the reporting plugin in the repository * @return the key of the plugin, ie {@code groupId:artifactId} */ - public static String constructKey(String groupId, String artifactId) { + public static String constructKey(@Nullable String groupId, @Nullable String artifactId) { return groupId + ":" + artifactId; } @@ -2850,7 +2852,7 @@ @Override public String toString() { - return getId(); + return String.valueOf(getId()); } ]]> </code> @@ -3365,7 +3367,7 @@ <version>4.0.0+</version> <code> <![CDATA[ - private java.util.Map<String, ReportSet> reportSetMap = null; + @Nullable private java.util.Map<String, ReportSet> reportSetMap = null; /** * Reset the {@code reportSetMap} field to {@code null} @@ -3404,7 +3406,7 @@ * @param artifactId The artifact ID of the reporting plugin in the repository * @return the key of the report plugin, ie {@code groupId:artifactId} */ - public static String constructKey(String groupId, String artifactId) { + public static String constructKey(@Nullable String groupId, @Nullable String artifactId) { return groupId + ":" + artifactId; } ]]> @@ -3445,7 +3447,7 @@ <![CDATA[ @Override public String toString() { - return getId(); + return String.valueOf(getId()); } ]]> </code> diff --git a/api/maven-api-plugin/src/main/mdo/lifecycle.mdo b/api/maven-api-plugin/src/main/mdo/lifecycle.mdo index c7e4539adb..577846281b 100644 --- a/api/maven-api-plugin/src/main/mdo/lifecycle.mdo +++ b/api/maven-api-plugin/src/main/mdo/lifecycle.mdo @@ -120,6 +120,7 @@ under the License. * * @return String */ + @Nullable public String getEffectiveId() { if (executionPoint == null) { if (priority == 0) { diff --git a/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelParserException.java b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelParserException.java index 4520f0650b..91d5f8d5ec 100644 --- a/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelParserException.java +++ b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelParserException.java @@ -19,6 +19,7 @@ package org.apache.maven.api.spi; import org.apache.maven.api.annotations.Experimental; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.services.MavenException; @Experimental @@ -38,21 +39,21 @@ public ModelParserException() { this(null, null); } - public ModelParserException(String message) { + public ModelParserException(@Nullable String message) { this(message, null); } - public ModelParserException(String message, Throwable cause) { + public ModelParserException(@Nullable String message, @Nullable Throwable cause) { this(message, -1, -1, cause); } - public ModelParserException(String message, int lineNumber, int columnNumber, Throwable cause) { + public ModelParserException(@Nullable String message, int lineNumber, int columnNumber, @Nullable Throwable cause) { super(message, cause); this.lineNumber = lineNumber; this.columnNumber = columnNumber; } - public ModelParserException(Throwable cause) { + public ModelParserException(@Nullable Throwable cause) { this(null, cause); } diff --git a/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelTransformerException.java b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelTransformerException.java index d2f8443826..b72d4d507a 100644 --- a/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelTransformerException.java +++ b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ModelTransformerException.java @@ -19,6 +19,7 @@ package org.apache.maven.api.spi; import org.apache.maven.api.annotations.Experimental; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.services.MavenException; @Experimental @@ -28,15 +29,15 @@ public ModelTransformerException() { this(null, null); } - public ModelTransformerException(String message) { + public ModelTransformerException(@Nullable String message) { this(message, null); } - public ModelTransformerException(Throwable cause) { + public ModelTransformerException(@Nullable Throwable cause) { this(null, cause); } - public ModelTransformerException(String message, Throwable cause) { + public ModelTransformerException(@Nullable String message, @Nullable Throwable cause) { super(message, cause); } } diff --git a/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/ImmutableCollections.java b/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/ImmutableCollections.java index 80abc22030..dbd12ad460 100644 --- a/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/ImmutableCollections.java +++ b/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/ImmutableCollections.java @@ -31,6 +31,8 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.apache.maven.api.annotations.Nullable; + /** * This should be removed when https://bugs.openjdk.org/browse/JDK-8323729 * is released in our minimum JDK. @@ -64,11 +66,11 @@ public int size() { } }; - static <E1, E2 extends E1> List<E1> copy(Collection<E2> collection) { + static <E1, E2 extends E1> List<E1> copy(@Nullable Collection<E2> collection) { return collection == null ? List.of() : List.copyOf(collection); } - static <K, V> Map<K, V> copy(Map<K, V> map) { + static <K, V> Map<K, V> copy(@Nullable Map<K, V> map) { if (map == null) { return emptyMap(); } else if (map instanceof AbstractImmutableMap) { diff --git a/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlNode.java b/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlNode.java index a78357a091..9b5303d1b3 100644 --- a/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlNode.java +++ b/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlNode.java @@ -244,6 +244,7 @@ default Object getInputLocation() { * @deprecated use {@link XmlService#merge(XmlNode, XmlNode, Boolean)} instead */ @Deprecated(since = "4.0.0", forRemoval = true) + @Nullable default XmlNode merge(@Nullable XmlNode source) { return XmlService.merge(this, source); } @@ -252,6 +253,7 @@ default XmlNode merge(@Nullable XmlNode source) { * @deprecated use {@link XmlService#merge(XmlNode, XmlNode, Boolean)} instead */ @Deprecated(since = "4.0.0", forRemoval = true) + @Nullable default XmlNode merge(@Nullable XmlNode source, @Nullable Boolean childMergeOverride) { return XmlService.merge(this, source, childMergeOverride); } @@ -353,12 +355,25 @@ static Builder newBuilder() { * {@link #build()}. */ class Builder { + @Nullable private String name; + + @Nullable private String value; + + @Nullable private String namespaceUri; + + @Nullable private String prefix; + + @Nullable private Map<String, String> attributes; + + @Nullable private List<XmlNode> children; + + @Nullable private Object inputLocation; /** @@ -458,30 +473,41 @@ public XmlNode build() { } private record Impl( - String prefix, - String namespaceUri, + @Nonnull String prefix, + @Nonnull String namespaceUri, @Nonnull String name, - String value, + @Nullable String value, @Nonnull Map<String, String> attributes, @Nonnull List<XmlNode> children, - Object inputLocation) + @Nullable Object inputLocation) implements XmlNode, Serializable { - private Impl { + private Impl( + @Nullable String prefix, + @Nullable String namespaceUri, + @Nullable String name, + @Nullable String value, + @Nullable Map<String, String> attributes, + @Nullable List<XmlNode> children, + @Nullable Object inputLocation) { // Validation and normalization from the original constructor - prefix = prefix == null ? "" : prefix; - namespaceUri = namespaceUri == null ? "" : namespaceUri; - name = Objects.requireNonNull(name); - attributes = ImmutableCollections.copy(attributes); - children = ImmutableCollections.copy(children); + this.prefix = prefix == null ? "" : prefix; + this.namespaceUri = namespaceUri == null ? "" : namespaceUri; + this.name = Objects.requireNonNull(name); + this.value = value; + this.attributes = ImmutableCollections.copy(attributes); + this.children = ImmutableCollections.copy(children); + this.inputLocation = inputLocation; } @Override + @Nullable public String attribute(@Nonnull String name) { return attributes.get(name); } @Override + @Nullable public XmlNode child(String name) { if (name != null) { ListIterator<XmlNode> it = children.listIterator(children.size()); @@ -528,7 +554,7 @@ private String toStringObject() { w = addToStringField(sb, prefix, o -> !o.isEmpty(), "prefix", w); w = addToStringField(sb, namespaceUri, o -> !o.isEmpty(), "namespaceUri", w); w = addToStringField(sb, name, o -> !o.isEmpty(), "name", w); - w = addToStringField(sb, value, o -> !o.isEmpty(), "value", w); + w = addToStringField(sb, value, o -> o != null && !o.isEmpty(), "value", w); w = addToStringField(sb, attributes, o -> !o.isEmpty(), "attributes", w); w = addToStringField(sb, children, o -> !o.isEmpty(), "children", w); w = addToStringField(sb, inputLocation, Objects::nonNull, "inputLocation", w); @@ -537,7 +563,7 @@ private String toStringObject() { } private static <T> boolean addToStringField( - StringBuilder sb, T o, Function<T, Boolean> p, String n, boolean w) { + StringBuilder sb, @Nullable T o, Function<T, Boolean> p, String n, boolean w) { if (!p.apply(o)) { if (w) { sb.append(", "); diff --git a/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlService.java b/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlService.java index e6735e255f..a173026968 100644 --- a/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlService.java +++ b/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlService.java @@ -106,7 +106,7 @@ public abstract class XmlService { * Convenience method to merge two XML nodes using default settings. */ @Nullable - public static XmlNode merge(XmlNode dominant, XmlNode recessive) { + public static XmlNode merge(@Nullable XmlNode dominant, @Nullable XmlNode recessive) { return merge(dominant, recessive, null); } @@ -184,7 +184,7 @@ public interface InputLocationBuilder { * @return the parsed XML node * @throws XMLStreamException if there is an error parsing the XML */ - protected abstract XmlNode doRead(InputStream input, InputLocationBuilder locationBuilder) + protected abstract XmlNode doRead(InputStream input, @Nullable InputLocationBuilder locationBuilder) throws XMLStreamException; /** @@ -195,7 +195,8 @@ protected abstract XmlNode doRead(InputStream input, InputLocationBuilder locati * @return the parsed XML node * @throws XMLStreamException if there is an error parsing the XML */ - protected abstract XmlNode doRead(Reader reader, InputLocationBuilder locationBuilder) throws XMLStreamException; + protected abstract XmlNode doRead(Reader reader, @Nullable InputLocationBuilder locationBuilder) + throws XMLStreamException; /** * Implementation method for reading an XML node from an XMLStreamReader. @@ -205,7 +206,7 @@ protected abstract XmlNode doRead(InputStream input, InputLocationBuilder locati * @return the parsed XML node * @throws XMLStreamException if there is an error parsing the XML */ - protected abstract XmlNode doRead(XMLStreamReader reader, InputLocationBuilder locationBuilder) + protected abstract XmlNode doRead(XMLStreamReader reader, @Nullable InputLocationBuilder locationBuilder) throws XMLStreamException; /** @@ -225,7 +226,9 @@ protected abstract XmlNode doRead(XMLStreamReader reader, InputLocationBuilder l * @param childMergeOverride optional override for the child merge mode * @return the merged XML node, or null if both inputs are null */ - protected abstract XmlNode doMerge(XmlNode dominant, XmlNode recessive, Boolean childMergeOverride); + @Nullable + protected abstract XmlNode doMerge( + @Nullable XmlNode dominant, @Nullable XmlNode recessive, @Nullable Boolean childMergeOverride); /** * Gets the singleton instance of the XmlService. diff --git a/pom.xml b/pom.xml index 6437ae1709..7ef12f71a4 100644 --- a/pom.xml +++ b/pom.xml @@ -1254,5 +1254,52 @@ under the License. </plugins> </build> </profile> + <profile> + <id>nullaway</id> + <properties> + <errorProneVersion>2.36.0</errorProneVersion> + <nullawayVersion>0.12.6</nullawayVersion> + </properties> + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <fork>true</fork> + <compilerArgs> + <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg> + <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg> + <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg> + <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg> + <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg> + <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg> + <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg> + <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg> + <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg> + <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg> + <arg>-XDcompilePolicy=simple</arg> + <arg>-XDshould-stop.ifError=FLOW</arg> + <arg>-Xplugin:ErrorProne -XepDisableAllChecks -Xep:NullAway:WARN -XepOpt:NullAway:AnnotatedPackages=org.apache.maven -XepOpt:NullAway:CustomNullableAnnotations=org.apache.maven.api.annotations.Nullable -XepOpt:NullAway:CustomNonnullAnnotations=org.apache.maven.api.annotations.Nonnull</arg> + </compilerArgs> + <annotationProcessorPaths> + <path> + <groupId>com.google.errorprone</groupId> + <artifactId>error_prone_core</artifactId> + <version>${errorProneVersion}</version> + </path> + <path> + <groupId>com.uber.nullaway</groupId> + <artifactId>nullaway</artifactId> + <version>${nullawayVersion}</version> + </path> + </annotationProcessorPaths> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + </profile> </profiles> </project> diff --git a/src/mdo/java/ImmutableCollections.java b/src/mdo/java/ImmutableCollections.java index 9e205f18cf..ff5eb059b7 100644 --- a/src/mdo/java/ImmutableCollections.java +++ b/src/mdo/java/ImmutableCollections.java @@ -31,6 +31,8 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.apache.maven.api.annotations.Nullable; + /** * This should be removed when https://bugs.openjdk.org/browse/JDK-8323729 * is released in our minimum JDK. @@ -64,11 +66,11 @@ public int size() { } }; - static <E1, E2 extends E1> List<E1> copy(Collection<E2> collection) { + static <E1, E2 extends E1> List<E1> copy(@Nullable Collection<E2> collection) { return collection == null ? List.of() : List.copyOf(collection); } - static <K, V> Map<K, V> copy(Map<K, V> map) { + static <K, V> Map<K, V> copy(@Nullable Map<K, V> map) { if (map == null) { return emptyMap(); } else if (map instanceof AbstractImmutableMap) { diff --git a/src/mdo/java/InputLocation.java b/src/mdo/java/InputLocation.java index c01343ad67..5ba8170175 100644 --- a/src/mdo/java/InputLocation.java +++ b/src/mdo/java/InputLocation.java @@ -25,6 +25,8 @@ import java.util.Map; import java.util.Objects; +import org.apache.maven.api.annotations.Nullable; + /** * Represents the location of an element within a model source file. * <p> @@ -42,14 +44,14 @@ public final class InputLocation implements Serializable, InputLocationTracker { private final int lineNumber; private final int columnNumber; - private final InputSource source; + @Nullable private final InputSource source; private final Map<Object, InputLocation> locations; #if ( $isMavenModel ) - private final InputLocation importedFrom; + @Nullable private final InputLocation importedFrom; private volatile int hashCode = 0; // Cached hashCode for performance #else - private final InputLocation importedFrom; + @Nullable private final InputLocation importedFrom; #end private static final InputLocation EMPTY = new InputLocation(-1, -1); @@ -75,7 +77,7 @@ public final class InputLocation implements Serializable, InputLocationTracker { * @param columnNumber the column number in the source file (1-based) */ InputLocation(int lineNumber, int columnNumber) { - this(lineNumber, columnNumber, null, null); + this(lineNumber, columnNumber, (InputSource) null, null); } /** @@ -85,7 +87,7 @@ public final class InputLocation implements Serializable, InputLocationTracker { * @param columnNumber the column number in the source file (1-based) * @param source the input source where this location originates from */ - InputLocation(int lineNumber, int columnNumber, InputSource source) { + InputLocation(int lineNumber, int columnNumber, @Nullable InputSource source) { this(lineNumber, columnNumber, source, null); } @@ -97,7 +99,7 @@ public final class InputLocation implements Serializable, InputLocationTracker { * @param source the input source where this location originates from * @param selfLocationKey the key to map this location to itself in the locations map */ - InputLocation(int lineNumber, int columnNumber, InputSource source, Object selfLocationKey) { + InputLocation(int lineNumber, int columnNumber, @Nullable InputSource source, @Nullable Object selfLocationKey) { this.lineNumber = lineNumber; this.columnNumber = columnNumber; this.source = source; @@ -115,7 +117,7 @@ public final class InputLocation implements Serializable, InputLocationTracker { * @param source the input source where this location originates from * @param locations a map of keys to InputLocation instances for nested elements */ - InputLocation(int lineNumber, int columnNumber, InputSource source, Map<Object, InputLocation> locations) { + InputLocation(int lineNumber, int columnNumber, @Nullable InputSource source, @Nullable Map<Object, InputLocation> locations) { this.lineNumber = lineNumber; this.columnNumber = columnNumber; this.source = source; @@ -250,6 +252,7 @@ public int getColumnNumber() { * * @return the input source, or null if unknown */ + @Nullable public InputSource getSource() { return source; } @@ -260,10 +263,11 @@ public InputSource getSource() { * @param key the key to look up * @return the InputLocation for the specified key, or null if not found */ + @Nullable @Override public InputLocation getLocation(Object key) { Objects.requireNonNull(key, "key"); - return locations != null ? locations.get(key) : null; + return locations.get(key); } /** @@ -282,6 +286,7 @@ public Map<Object, InputLocation> getLocations() { * @return InputLocation * @since 4.0.0 */ + @Nullable @Override public InputLocation getImportedFrom() { return importedFrom; @@ -295,7 +300,8 @@ public InputLocation getImportedFrom() { * @param sourceDominant the boolean indicating of {@code source} is dominant compared to {@code target} * @return the merged location */ - public static InputLocation merge(InputLocation target, InputLocation source, boolean sourceDominant) { + @Nullable + public static InputLocation merge(@Nullable InputLocation target, @Nullable InputLocation source, boolean sourceDominant) { if (source == null) { return target; } else if (target == null) { @@ -332,7 +338,8 @@ public static InputLocation merge(InputLocation target, InputLocation source, bo * @param indices the list of integers for the indices * @return the merged location */ - public static InputLocation merge(InputLocation target, InputLocation source, Collection<Integer> indices) { + @Nullable + public static InputLocation merge(@Nullable InputLocation target, @Nullable InputLocation source, Collection<Integer> indices) { if (source == null) { return target; } else if (target == null) { @@ -389,9 +396,9 @@ && safeLocationsEquals(this, locations, that, that.locations) */ private static boolean safeLocationsEquals( InputLocation this1, - Map<Object, InputLocation> map1, + @Nullable Map<Object, InputLocation> map1, InputLocation this2, - Map<Object, InputLocation> map2) { + @Nullable Map<Object, InputLocation> map2) { if (map1 == map2) { return true; } @@ -433,7 +440,7 @@ public int hashCode() { return result; } - public int safeHash(Map<Object, InputLocation> locations) { + public int safeHash(@Nullable Map<Object, InputLocation> locations) { if (locations == null) { return 0; } diff --git a/src/mdo/java/InputLocationTracker.java b/src/mdo/java/InputLocationTracker.java index a70ac293cf..f4212817c8 100644 --- a/src/mdo/java/InputLocationTracker.java +++ b/src/mdo/java/InputLocationTracker.java @@ -18,6 +18,8 @@ */ package ${package}; +import org.apache.maven.api.annotations.Nullable; + /** * Tracks input source locations for model fields. * <p> @@ -35,6 +37,7 @@ public interface InputLocationTracker { * @return the location of the field in the input source or {@code null} if unknown * @throws NullPointerException if {@code field} is {@code null} */ + @Nullable InputLocation getLocation(Object field); /** @@ -44,5 +47,6 @@ public interface InputLocationTracker { * @return InputLocation * @since 4.0.0 */ + @Nullable InputLocation getImportedFrom(); } diff --git a/src/mdo/java/InputSource.java b/src/mdo/java/InputSource.java index 79eb0fb0f7..ee5bc7e7fc 100644 --- a/src/mdo/java/InputSource.java +++ b/src/mdo/java/InputSource.java @@ -25,6 +25,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.maven.api.annotations.Nullable; + /** * Represents the source of a model input, such as a POM file. * <p> @@ -41,22 +43,22 @@ public final class InputSource implements Serializable { #if ( $isMavenModel ) - private final String modelId; + @Nullable private final String modelId; #end - private final String location; - private final List<InputSource> inputs; - private final InputLocation importedFrom; + @Nullable private final String location; + @Nullable private final List<InputSource> inputs; + @Nullable private final InputLocation importedFrom; #if ( $isMavenModel ) private volatile int hashCode = 0; // Cached hashCode for performance #end #if ( $isMavenModel ) - public InputSource(String modelId, String location) { + public InputSource(@Nullable String modelId, @Nullable String location) { this(modelId, location, null); } - public InputSource(String modelId, String location, InputLocation importedFrom) { + public InputSource(@Nullable String modelId, @Nullable String location, @Nullable InputLocation importedFrom) { this.modelId = modelId; this.location = location; this.inputs = null; @@ -69,7 +71,7 @@ public InputSource(String modelId, String location, InputLocation importedFrom) * * @param location the path/URL of the input source, may be null */ - InputSource(String location) { + InputSource(@Nullable String location) { #if ( $isMavenModel ) this.modelId = null; #end @@ -150,6 +152,7 @@ public static InputSource of(Collection<InputSource> inputs) { * * @return the location string, or null if unknown */ + @Nullable public String getLocation() { return this.location; } @@ -160,6 +163,7 @@ public String getLocation() { * * @return the model id */ + @Nullable public String getModelId() { return this.modelId; } @@ -172,6 +176,7 @@ public String getModelId() { * @return InputLocation * @since 4.0.0 */ + @Nullable public InputLocation getImportedFrom() { return importedFrom; } @@ -237,9 +242,9 @@ public String toString() { return inputs.stream().map(InputSource::toString).collect(Collectors.joining(", ", "merged[", "]")); } #if ( $isMavenModel ) - return getModelId() != null ? getModelId() + " " + getLocation() : getLocation(); + return getModelId() != null ? getModelId() + " " + getLocation() : String.valueOf(getLocation()); #else - return getLocation(); + return String.valueOf(getLocation()); #end } @@ -251,7 +256,14 @@ public String toString() { * @param src2 the second input source to merge * @return a new merged InputSource containing all distinct sources from both inputs */ - public static InputSource merge(InputSource src1, InputSource src2) { + @Nullable + public static InputSource merge(@Nullable InputSource src1, @Nullable InputSource src2) { + if (src1 == null) { + return src2; + } + if (src2 == null) { + return src1; + } #if ( $isMavenModel ) return new InputSource( Stream.concat(src1.sources(), src2.sources()).distinct().toList()); diff --git a/src/mdo/model.vm b/src/mdo/model.vm index 481ee0b489..935d266a4a 100644 --- a/src/mdo/model.vm +++ b/src/mdo/model.vm @@ -59,6 +59,7 @@ #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Immutable" ) ) #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Nonnull" ) ) #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.NotThreadSafe" ) ) + #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Nullable" ) ) #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.ThreadSafe" ) ) #if ( $package == "org.apache.maven.api.model" ) #set ( $dummy = $imports.add( "org.apache.maven.api.model.ModelObjectProcessor" ) ) @@ -133,7 +134,9 @@ public class ${class.name} #end { #if ( $class == $root ) + @Nullable final String namespaceUri; + @Nullable final String modelEncoding; #end #foreach ( $field in $class.getFields($version) ) @@ -146,12 +149,16 @@ public class ${class.name} #foreach( $ann in ${field.annotations} ) ${ann} #end + #if ( $field.type != "java.util.List" && $field.type != "java.util.Properties" && $field.type != "java.util.Map" && $field.type != "boolean" && $field.type != "int" ) + @Nullable + #end final ${type} $field.name; #end #if ( $locationTracking && ! $class.superClass ) /** Locations */ final Map<Object, InputLocation> locations; /** Location tracking */ + @Nullable final InputLocation importedFrom; #end @@ -204,10 +211,12 @@ public class ${class.name} #end #if ( $class == $root ) + @Nullable public String getNamespaceUri() { return namespaceUri; } + @Nullable public String getModelEncoding() { return modelEncoding; } @@ -234,6 +243,8 @@ public class ${class.name} #end #if ( $field.type == "java.util.List" || $field.type == "java.util.Properties" ) @Nonnull + #elseif ( $field.type != "boolean" && $field.type != "int" ) + @Nullable #end public ${type} ${pfx}${cap}() { return this.${field.name}; @@ -248,6 +259,7 @@ public class ${class.name} * @return the location of the field in the input source or {@code null} if unknown * @throws NullPointerException if {@code key} is {@code null} */ + @Nullable public InputLocation getLocation(Object key) { Objects.requireNonNull(key, "key"); return locations.get(key); @@ -267,6 +279,7 @@ public class ${class.name} /** * Gets the input location that caused this model to be read. */ + @Nullable public InputLocation getImportedFrom() { return importedFrom; } @@ -384,10 +397,10 @@ public class ${class.name} extends ${class.superClass}.Builder #end { - ${class.name} base; + @Nullable ${class.name} base; #if ( $class == $root ) - String namespaceUri; - String modelEncoding; + @Nullable String namespaceUri; + @Nullable String modelEncoding; #end #foreach ( $field in $class.getFields($version) ) #set ( $type = ${types.getOrDefault($field,${types.getOrDefault($field.type,$field.type)})} ) @@ -395,16 +408,16 @@ public class ${class.name} #set ( $type = ${type.replace('List<','Collection<')} ) #end #if ( $type == 'boolean' ) - Boolean ${field.name}; + @Nullable Boolean ${field.name}; #elseif ( $type == 'int' ) - Integer ${field.name}; + @Nullable Integer ${field.name}; #else - ${type} ${field.name}; + @Nullable ${type} ${field.name}; #end #end #if ( ! $class.superClass && $locationTracking ) - Map<Object, InputLocation> locations; - InputLocation importedFrom; + @Nullable Map<Object, InputLocation> locations; + @Nullable InputLocation importedFrom; #end protected Builder(boolean withDefaults) {
