Skip to content

Commit

Permalink
[MNG-8015] Adjustments in new API related to PathType (#1501)
Browse files Browse the repository at this point in the history
* Javadoc cleanup and replacement of some `System.getProperty("...")` by more specific standard methods.

* Add Type.PROCESSOR, MODULAR_PROCESSOR and CLASSPATH_PROCESSOR.

* Modification of the path type API:

* Add a `warningForFilenameBasedAutomodules()` method in `DependencyResolverResult`.
* Add relationships from `JavaPathType` to `javax.tool` location API.
* Modify the `PathType.option(Iterable<? extends Path>)` return type
  because the option and the value need to be two separated arguments.

* Fixes according some comments on the pull request.
  • Loading branch information
desruisseaux authored May 13, 2024
1 parent c363e27 commit 583667a
Show file tree
Hide file tree
Showing 15 changed files with 339 additions and 132 deletions.
129 changes: 101 additions & 28 deletions api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
*/
package org.apache.maven.api;

import javax.tools.DocumentationTool;
import javax.tools.JavaFileManager;
import javax.tools.StandardLocation;

import java.io.File;
import java.nio.file.Path;
import java.util.Objects;
Expand All @@ -40,6 +44,13 @@
* <p>Path types are often exclusive. For example, a dependency should not be both on the Java class-path
* and on the Java module-path.</p>
*
* <h2>Relationship with Java compiler standard location</h2>
* This enumeration is closely related to the {@link JavaFileManager.Location} enumerations.
* A difference is that the latter enumerates input and output files, while {@code JavaPathType}
* enumerates only input dependencies. Another difference is that {@code JavaPathType} contains
* some enumeration values used only at runtime and therefore not available in {@code javax.tool},
* such as agent paths.
*
* @see org.apache.maven.api.services.DependencyResolverResult#getDispatchedPaths()
*
* @since 4.0.0
Expand All @@ -49,11 +60,12 @@ public enum JavaPathType implements PathType {
/**
* The path identified by the Java {@code --class-path} option.
* Used for compilation, execution and Javadoc among others.
* The Java tools location is {@link StandardLocation#CLASS_PATH}.
*
* <p><b>Context-sensitive interpretation:</b>
* <h4>Context-sensitive interpretation</h4>
* A dependency with this path type will not necessarily be placed on the class-path.
* There are two circumstances where the dependency may nevertheless be placed somewhere else:
* </p>
*
* <ul>
* <li>If {@link #MODULES} path type is also set, then the dependency can be placed either on the
* class-path or on the module-path, but only one of those. The choice is up to the plugin,
Expand All @@ -63,16 +75,17 @@ public enum JavaPathType implements PathType {
* class-path.</li>
* </ul>
*/
CLASSES("--class-path"),
CLASSES(StandardLocation.CLASS_PATH, "--class-path"),

/**
* The path identified by the Java {@code --module-path} option.
* Used for compilation, execution and Javadoc among others.
* The Java tools location is {@link StandardLocation#MODULE_PATH}.
*
* <p><b>Context-sensitive interpretation:</b>
* <h4>Context-sensitive interpretation</h4>
* A dependency with this flag will not necessarily be placed on the module-path.
* There are two circumstances where the dependency may nevertheless be placed somewhere else:
* </p>
*
* <ul>
* <li>If {@link #CLASSES} path type is also set, then the dependency <em>should</em> be placed on the
* module-path, but is also compatible with placement on the class-path. Compatibility can
Expand All @@ -84,57 +97,63 @@ public enum JavaPathType implements PathType {
* {@code --module-path} option.</li>
* </ul>
*/
MODULES("--module-path"),
MODULES(StandardLocation.MODULE_PATH, "--module-path"),

/**
* The path identified by the Java {@code --upgrade-module-path} option.
* The Java tools location is {@link StandardLocation#UPGRADE_MODULE_PATH}.
*/
UPGRADE_MODULES("--upgrade-module-path"),
UPGRADE_MODULES(StandardLocation.UPGRADE_MODULE_PATH, "--upgrade-module-path"),

/**
* The path identified by the Java {@code --patch-module} option.
* The Java tools location is {@link StandardLocation#PATCH_MODULE_PATH}.
*
* Note that this option is incomplete, because it must be followed by a module name.
* Use this type only when the module to patch is unknown.
*
* @see #patchModule(String)
*/
PATCH_MODULE("--patch-module"),
PATCH_MODULE(StandardLocation.PATCH_MODULE_PATH, "--patch-module"),

/**
* The path identified by the Java {@code --processor-path} option.
* The Java tools location is {@link StandardLocation#ANNOTATION_PROCESSOR_PATH}.
*/
PROCESSOR_CLASSES("--processor-path"),
PROCESSOR_CLASSES(StandardLocation.ANNOTATION_PROCESSOR_PATH, "--processor-path"),

/**
* The path identified by the Java {@code --processor-module-path} option.
* The Java tools location is {@link StandardLocation#ANNOTATION_PROCESSOR_MODULE_PATH}.
*/
PROCESSOR_MODULES("--processor-module-path"),
PROCESSOR_MODULES(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH, "--processor-module-path"),

/**
* The path identified by the Java {@code -agentpath} option.
*/
AGENT("-agentpath"),
AGENT(null, "-agentpath"),

/**
* The path identified by the Javadoc {@code -doclet} option.
* The Java tools location is {@link DocumentationTool.Location#DOCLET_PATH}.
*/
DOCLET("-doclet"),
DOCLET(DocumentationTool.Location.DOCLET_PATH, "-doclet"),

/**
* The path identified by the Javadoc {@code -tagletpath} option.
* The Java tools location is {@link DocumentationTool.Location#TAGLET_PATH}.
*/
TAGLETS("-tagletpath");
TAGLETS(DocumentationTool.Location.TAGLET_PATH, "-tagletpath");

/**
* Creates a path identified by the Java {@code --patch-module} option.
* Contrarily to the other types of paths, this path is applied to only
* one specific module. Used for compilation and execution among others.
*
* <p><b>Context-sensitive interpretation:</b>
* <h4>Context-sensitive interpretation</h4>
* This path type makes sense only when a main module is added on the module-path by another dependency.
* In no main module is found, the patch dependency may be added on the class-path or module-path
* depending on whether {@link #CLASSES} or {@link #MODULES} is present.
* </p>
*
* @param moduleName name of the module on which to apply the path
* @return an identification of the patch-module path for the given module.
Expand All @@ -146,6 +165,13 @@ public static Modular patchModule(@Nonnull String moduleName) {
return PATCH_MODULE.new Modular(moduleName);
}

/**
* The {@code javax.tool} enumeration value corresponding to this {@code JavaPathType}, or {@code null} if none.
*
* @see #location()
*/
private final JavaFileManager.Location location;

/**
* The tools option for this path, or {@code null} if none.
*
Expand All @@ -156,17 +182,51 @@ public static Modular patchModule(@Nonnull String moduleName) {
/**
* Creates a new enumeration value for a path associated to the given tool option.
*
* @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(String option) {
JavaPathType(JavaFileManager.Location location, String option) {
this.location = location;
this.option = option;
}

/**
* Returns the unique name of this path type.
*
* @return the programmatic name of this enumeration value
*/
@Override
public String id() {
return name();
}

/**
* Returns the identification of this path in the {@code javax.tool} API.
* The value may be an instance of {@link StandardLocation} or {@link DocumentationTool.Location},
* depending which tool will use this location.
*
* @return the {@code javax.tool} enumeration value corresponding to this {@code JavaPathType}
*/
public Optional<JavaFileManager.Location> location() {
return Optional.ofNullable(location);
}

/**
* Returns the path type associated to the given {@code javax.tool} location.
* This method is the converse of {@link #location()}.
*
* @param location identification of a path in the {@code javax.tool} API
* @return Java path type associated to the given location
*/
public static Optional<JavaPathType> valueOf(JavaFileManager.Location location) {
for (JavaPathType type : JavaPathType.values()) {
if (location.equals(type.location)) {
return Optional.of(type);
}
}
return Optional.empty();
}

/**
* Returns the name of the tool option for this path. For example, if this path type
* is {@link #MODULES}, then this method returns {@code "--module-path"}. The option
Expand All @@ -187,31 +247,38 @@ public Optional<String> option() {
*
* @param paths the path to format as a tool option
* @return the option associated to this path type followed by the given path elements,
* or an empty string if there is no path element
* or an empty array if there is no path element
* @throws IllegalStateException if no option is associated to this path type
*/
@Nonnull
@Override
public String option(Iterable<? extends Path> paths) {
public String[] option(Iterable<? extends Path> paths) {
return format(null, paths);
}

/**
* Implementation shared with {@link Modular}.
*/
String format(String moduleName, Iterable<? extends Path> paths) {
final String[] format(String moduleName, Iterable<? extends Path> paths) {
if (option == null) {
throw new IllegalStateException("No option is associated to this path type.");
}
String prefix = (moduleName == null) ? (option + ' ') : (option + ' ' + moduleName + '=');
String prefix = (moduleName == null) ? "" : (moduleName + '=');
StringJoiner joiner = new StringJoiner(File.pathSeparator, prefix, "");
joiner.setEmptyValue("");
for (Path p : paths) {
joiner.add(p.toString());
}
return joiner.toString();
String value = joiner.toString();
if (value.isEmpty()) {
return new String[0];
}
return new String[] {option, value};
}

/**
* {@return a string representation of this path type for debugging purposes}.
*/
@Override
public String toString() {
return "PathType[" + id() + "]";
Expand Down Expand Up @@ -240,11 +307,6 @@ private Modular(@Nonnull String moduleName) {
this.moduleName = Objects.requireNonNull(moduleName);
}

@Override
public String id() {
return JavaPathType.this.name() + ":" + moduleName;
}

/**
* Returns the type of path without indication about the target module.
* This is usually {@link #PATCH_MODULE}.
Expand All @@ -256,12 +318,23 @@ public JavaPathType rawType() {
return JavaPathType.this;
}

/**
* Returns the name of the tool option for this path, including the module name.
*
* @return name of the tool option for this path, including the module name
*/
@Override
public String id() {
return JavaPathType.this.name() + ":" + moduleName;
}

/**
* Returns the name of the tool option for this path, not including the module name.
*
* @return name of the tool option for this path, not including the module name
*/
@Nonnull
@Override
public String name() {
return JavaPathType.this.name();
}
Expand Down Expand Up @@ -295,11 +368,11 @@ public Optional<String> option() {
*
* @param paths the path to format as a string
* @return the option associated to this path type followed by the given path elements,
* or an empty string if there is no path element.
* or an empty array if there is no path element.
*/
@Nonnull
@Override
public String option(Iterable<? extends Path> paths) {
public String[] option(Iterable<? extends Path> paths) {
return format(moduleName, paths);
}

Expand Down
23 changes: 12 additions & 11 deletions api/maven-api-core/src/main/java/org/apache/maven/api/PathType.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public Optional<String> option() {
}

@Override
public String option(Iterable<? extends Path> paths) {
return "";
public String[] option(Iterable<? extends Path> paths) {
return new String[0];
}
};

Expand Down Expand Up @@ -94,23 +94,24 @@ public String option(Iterable<? extends Path> paths) {
* The path elements are separated by an option-specific or platform-specific separator.
* If the given {@code paths} argument contains no element, then this method returns an empty string.
*
* <p><b>Examples:</b>
* If {@code paths} is a list containing two elements, {@code path1} and {@code path2}, then:
* </p>
* <h4>Examples</h4>
* If {@code paths} is a list containing two elements, {@code dir/path1} and {@code dir/path2}, then:
*
* <ul>
* <li>If this type is {@link JavaPathType#MODULES}, then this method returns
* {@code "--module-path path1:path2"} on Unix or {@code "--module-path path1;path2"} on Windows.</li>
* {@code {"--module-path", "dir/path1:dir/path2"}} on Unix or
* {@code {"--module-path", "dir\path1;dir\path2"}} on Windows.</li>
* <li>If this type was created by {@code JavaPathType.patchModule("foo.bar")}, then the method returns
* {@code "--patch-module foo.bar=path1:path2"} on Unix or {@code "--patch-module foo.bar=path1;path2"}
* on Windows.</li>
* {@code {"--patch-module", "foo.bar=dir/path1:dir/path2"}} on Unix or
* {@code {"--patch-module", "foo.bar=dir\path1;dir\path2"}} on Windows.</li>
* </ul>
*
* @param paths the path to format as a string
* @return the option associated to this path type followed by the given path elements,
* or an empty string if there is no path element.
* or an empty array if there is no path element.
*/
@Nonnull
String option(Iterable<? extends Path> paths);
String[] option(Iterable<? extends Path> paths);

/**
* Returns the name of this path type. For example, if this path type
Expand All @@ -122,7 +123,7 @@ public String option(Iterable<? extends Path> paths) {
String name();

/**
* Returns a string representation for this extensible enum describing a path type.
* {@return a string representation for this extensible enum describing a path type}.
* For example {@code "PathType[PATCH_MODULE:foo.bar]"}.
*/
@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
@Experimental
public interface Toolchain {
/**
* get the type of toolchain.
* Gets the type of toolchain.
*
* @return the toolchain type
*/
Expand All @@ -47,7 +47,8 @@ public interface Toolchain {
/**
* Let the toolchain decide if it matches requirements defined
* in the toolchain plugin configuration.
* @param requirements Map&lt;String, String&gt; key value pair, may not be {@code null}
*
* @param requirements key value pair, may not be {@code null}
* @return {@code true} if the requirements match, otherwise {@code false}
*/
boolean matchesRequirements(Map<String, String> requirements);
Expand Down
18 changes: 18 additions & 0 deletions api/maven-api-core/src/main/java/org/apache/maven/api/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,24 @@ public interface Type extends ExtensibleEnum {
*/
String MODULAR_JAR = "modular-jar";

/**
* Artifact type name for a JAR file that can be placed either on the annotation processor class-path
* or module-path. The path (classes or modules) is chosen by the plugin, possibly using heuristic rules.
*/
String PROCESSOR = "processor";

/**
* Artifact type name for a JAR file to unconditionally place on the annotation processor class-path.
* If the JAR is modular, its module information are ignored.
*/
String CLASSPATH_PROCESSOR = "classpath-processor";

/**
* Artifact type name for a JAR file to unconditionally place on the annotation processor module-path.
* If the JAR is not modular, then it is loaded by Java as an unnamed module.
*/
String MODULAR_PROCESSOR = "modular-processor";

/**
* Artifact type name for source code packaged in a JAR file.
*/
Expand Down
Loading

0 comments on commit 583667a

Please sign in to comment.