[
https://issues.apache.org/jira/browse/MNG-8015?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17807623#comment-17807623
]
ASF GitHub Bot commented on MNG-8015:
-------------------------------------
gnodet commented on code in PR #1378:
URL: https://github.com/apache/maven/pull/1378#discussion_r1453039589
##########
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java:
##########
@@ -33,27 +36,226 @@
@Immutable
public interface DependencyProperties {
/**
- * Boolean flag telling that dependency contains all of its dependencies.
Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Keys in the dependency properties map.
+ * Each key can be associated to values of a specific class.
+ *
+ * @param <V> type of value associated to the key
+ */
+ class Key<V> {
+ /**
+ * The keys that are defined in this {@code DependencyProperties} map.
+ * Accesses to this map shall be synchronized on the map.
+ *
+ * @see #intern()
+ */
+ private static final Map<String, Key<?>> INTERNS = new HashMap<>();
Review Comment:
Can we use a `ConcurrentHashMap` rather than a `HashMap` and synchronizing
access to it ?
##########
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java:
##########
@@ -33,27 +36,226 @@
@Immutable
public interface DependencyProperties {
/**
- * Boolean flag telling that dependency contains all of its dependencies.
Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Keys in the dependency properties map.
+ * Each key can be associated to values of a specific class.
+ *
+ * @param <V> type of value associated to the key
+ */
+ class Key<V> {
+ /**
+ * The keys that are defined in this {@code DependencyProperties} map.
+ * Accesses to this map shall be synchronized on the map.
+ *
+ * @see #intern()
+ */
+ private static final Map<String, Key<?>> INTERNS = new HashMap<>();
+
+ /**
+ * Value returned by {@link #name()}.
+ */
+ @Nonnull
+ private final String name;
+
+ /**
+ * Value returned by {@link #valueType()}.
+ */
+ @Nonnull
+ private final Class<V> valueType;
+
+ /**
+ * Creates a new key.
+ *
+ * @param name name of the key
+ * @param valueType type of value associated to the key
+ */
+ public Key(@Nonnull final String name, @Nonnull final Class<V>
valueType) {
+ this.name = Objects.requireNonNull(name);
+ this.valueType = Objects.requireNonNull(valueType);
+ }
+
+ /**
+ * If a key exists in the {@linkplain #intern() intern pool} for the
given name, returns that key.
+ * Otherwise, if the {@code defaultType} is non-null, creates a key
for values of the specified type.
+ * Otherwise, returns {@code null}.
+ *
+ * @param name name of the key to search or create
+ * @param defaultType value type of the key to create if none exist
for the given name, or {@code null}
+ * @return key found or created, or {@code null} if no key was found
and {@code defaultType} is null
+ *
+ * @see #intern()
+ */
+ public static Key<?> forName(String name, Class<?> defaultType) {
+ Key<?> key;
+ synchronized (INTERNS) {
+ key = INTERNS.get(name);
+ }
+ if (key == null && defaultType != null) {
+ key = new Key<>(name, defaultType);
+ }
+ return key;
+ }
+
+ /**
+ * {@return the name of the key}.
+ */
+ @Nonnull
+ public String name() {
+ return name;
+ }
+
+ /**
+ * {@return the type of value associated to the key}.
+ */
+ @Nonnull
+ public Class<V> valueType() {
+ return valueType;
+ }
+
+ /**
+ * {@return a canonical representation of this key}. A pool of keys,
initially empty, is maintained privately.
+ * When the {@code intern()} method is invoked, if the pool already
contains a key equal to this {@code Key}
+ * as determined by the {@link #equals(Object)} method, then the key
from the pool is returned. Otherwise,
+ * if no key exist in the pool for this key {@linkplain #name() name},
then this {@code Key} object is added
+ * to the pool and {@code this} is returned. Otherwise an {@link
IllegalStateException} is thrown.
+ *
+ * @throws IllegalStateException if a key exists in the pool for the
same name but a different class of values.
+ *
+ * @see String#intern()
+ */
+ @SuppressWarnings("unchecked")
+ public Key<V> intern() {
+ Key<?> previous;
+ synchronized (INTERNS) {
+ previous = INTERNS.putIfAbsent(name, this);
+ }
+ if (previous == null) {
+ return this;
+ }
+ if (equals(previous)) {
+ return (Key<V>) previous;
+ }
+ throw new IllegalStateException("Key " + name + " already exists
for a different class of values.");
+ }
+
+ /**
+ * {@return a string representation of this key}.
+ * By default, this is the name of this key.
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * {@return an hash code value for this key}.
+ */
+ @Override
+ public int hashCode() {
+ return 7 + name.hashCode() + 31 * valueType.hashCode();
Review Comment:
`Objects.hash(name, valueType)`
##########
api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java:
##########
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.StringJoiner;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * The option of a Java command-line tool where to place the paths to some
dependencies.
+ * A {@code PathType} can identify the class-path, the module-path, the
patches for a specific module,
+ * or another kind of path. This class is like an enumeration, except that it
is extensible:
+ * plugins can define their own kinds of path.
+ *
+ * <p>One path type is handled in a special way: contrarily to other options,
+ * the paths specified in a {@code --patch-module} Java option is effective
only for a specified module.
+ * This type is created by calls to {@link #patchModule(String)} and a new
instance must be created for
+ * every module to patch.</p>
+ *
+ * <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>
+ *
+ * @see
org.apache.maven.api.services.DependencyResolverResult#getDispatchedPaths()
+ *
+ * @since 4.0.0
+ */
+@Experimental
+public final class JavaPathType extends PathType {
+ /**
+ * The path identified by the Java {@code --class-path} option.
+ * Used for compilation, execution and Javadoc among others.
+ *
+ * <h4>Context-sensitive interpretation</h4>
+ * A dependency with this path type will not necessarily be placed on the
class-path.
+ * There is two circumstances where the dependency may be nevertheless
placed somewhere else:
+ *
+ * <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,
+ * possibly using heuristic rules (Maven 3 behavior).</li>
+ * <li>If a {@link #patchModule(String)} is also set and the main JAR
file was placed on the module-path,
+ * then the test dependency will be placed on the Java {@code
--patch-module} option instead of the
+ * class-path.</li>
+ * </ul>
+ */
+ public static final JavaPathType CLASSES = new JavaPathType("CLASSES",
"--class-path", null);
+
+ /**
+ * The path identified by the Java {@code --module-path} option.
+ * Used for compilation, execution and Javadoc among others.
+ *
+ * <h4>Context-sensitive interpretation</h4>
+ * A dependency with this flag will not necessarily be placed on the
module-path.
+ * There is two circumstances where the dependency may be nevertheless
placed somewhere else:
+ *
+ * <ul>
+ * <li>If {@link #CLASSES} path type is also set, then the dependency
<em>should</em> be placed on the
+ * module-path, but is nevertheless compatible with placement on the
class-path. Compatibility can
Review Comment:
`nevertheless` -> `also`
##########
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java:
##########
@@ -33,27 +36,226 @@
@Immutable
public interface DependencyProperties {
/**
- * Boolean flag telling that dependency contains all of its dependencies.
Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Keys in the dependency properties map.
+ * Each key can be associated to values of a specific class.
+ *
+ * @param <V> type of value associated to the key
+ */
+ class Key<V> {
+ /**
+ * The keys that are defined in this {@code DependencyProperties} map.
+ * Accesses to this map shall be synchronized on the map.
+ *
+ * @see #intern()
+ */
+ private static final Map<String, Key<?>> INTERNS = new HashMap<>();
+
+ /**
+ * Value returned by {@link #name()}.
+ */
+ @Nonnull
+ private final String name;
+
+ /**
+ * Value returned by {@link #valueType()}.
+ */
+ @Nonnull
+ private final Class<V> valueType;
+
+ /**
+ * Creates a new key.
+ *
+ * @param name name of the key
+ * @param valueType type of value associated to the key
+ */
+ public Key(@Nonnull final String name, @Nonnull final Class<V>
valueType) {
+ this.name = Objects.requireNonNull(name);
+ this.valueType = Objects.requireNonNull(valueType);
+ }
+
+ /**
+ * If a key exists in the {@linkplain #intern() intern pool} for the
given name, returns that key.
+ * Otherwise, if the {@code defaultType} is non-null, creates a key
for values of the specified type.
+ * Otherwise, returns {@code null}.
+ *
+ * @param name name of the key to search or create
+ * @param defaultType value type of the key to create if none exist
for the given name, or {@code null}
+ * @return key found or created, or {@code null} if no key was found
and {@code defaultType} is null
+ *
+ * @see #intern()
+ */
+ public static Key<?> forName(String name, Class<?> defaultType) {
+ Key<?> key;
+ synchronized (INTERNS) {
+ key = INTERNS.get(name);
+ }
+ if (key == null && defaultType != null) {
+ key = new Key<>(name, defaultType);
+ }
+ return key;
+ }
+
+ /**
+ * {@return the name of the key}.
+ */
+ @Nonnull
+ public String name() {
+ return name;
+ }
+
+ /**
+ * {@return the type of value associated to the key}.
+ */
+ @Nonnull
+ public Class<V> valueType() {
+ return valueType;
+ }
+
+ /**
+ * {@return a canonical representation of this key}. A pool of keys,
initially empty, is maintained privately.
+ * When the {@code intern()} method is invoked, if the pool already
contains a key equal to this {@code Key}
+ * as determined by the {@link #equals(Object)} method, then the key
from the pool is returned. Otherwise,
+ * if no key exist in the pool for this key {@linkplain #name() name},
then this {@code Key} object is added
+ * to the pool and {@code this} is returned. Otherwise an {@link
IllegalStateException} is thrown.
+ *
+ * @throws IllegalStateException if a key exists in the pool for the
same name but a different class of values.
+ *
+ * @see String#intern()
+ */
+ @SuppressWarnings("unchecked")
+ public Key<V> intern() {
+ Key<?> previous;
+ synchronized (INTERNS) {
+ previous = INTERNS.putIfAbsent(name, this);
+ }
+ if (previous == null) {
+ return this;
+ }
+ if (equals(previous)) {
+ return (Key<V>) previous;
+ }
+ throw new IllegalStateException("Key " + name + " already exists
for a different class of values.");
+ }
+
+ /**
+ * {@return a string representation of this key}.
+ * By default, this is the name of this key.
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * {@return an hash code value for this key}.
+ */
+ @Override
+ public int hashCode() {
+ return 7 + name.hashCode() + 31 * valueType.hashCode();
+ }
+
+ /**
+ * Compares this key with the given object for equality.
+ * Two keys are considered equal if they have the same name
+ * and are associated to values of the same class.
+ *
+ * @param obj the object to compare with this key
+ * @return whether the given object is equal to this key
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj != null && getClass() == obj.getClass()) {
+ final Key<?> other = (Key<?>) obj;
+ return name.equals(other.name) &&
valueType.equals(other.valueType);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * The dependency type. The {@linkplain Key#name() name} of this property
+ * is equal to the {@code ArtifactProperties.TYPE} value.
+ */
+ Key<String> TYPE = new Key<>("type", String.class).intern();
+
+ /**
+ * The dependency language. The {@linkplain Key#name() name} of this
property
+ * is equal to the {@code ArtifactProperties.LANGUAGE} value.
+ */
+ Key<String> LANGUAGE = new Key<>("language", String.class).intern();
+
+ /**
+ * Types of path (class-path, module-path, …) where the dependency can be
placed.
+ * For most deterministic builds, the array length should be 1. In such
case,
+ * the dependency will be unconditionally placed on the specified type of
path
+ * and no heuristic rule will be involved.
+ *
+ * <p>It is nevertheless common to specify two or more types of path. For
example,
+ * a Java library may be compatible with either the class-path or the
module-path,
+ * and the user may have provided no instruction about which type to use.
In such
+ * case, the plugin may apply rules for choosing a path. See for example
+ * {@link JavaPathType#CLASSES} and {@link JavaPathType#MODULES}.</p>
+ */
+ Key<PathType[]> PATH_TYPES = new Key<>("pathTypes",
PathType[].class).intern();
+
+ /**
+ * Boolean flag telling that dependency contains all of its dependencies.
* <p>
* <em>Important: this flag must be kept in sync with resolver! (as is
used during collection)</em>
*/
- String FLAG_INCLUDES_DEPENDENCIES = "includesDependencies";
+ Key<Boolean> FLAG_INCLUDES_DEPENDENCIES = new
Key<>("includesDependencies", Boolean.class).intern();
/**
- * Boolean flag telling that dependency is meant to be placed on class
path. Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Boolean flag telling that dependency is meant to be placed on class
path.
+ *
+ * @deprecated Use {@link #PATH_TYPES} and {@link JavaPathType#CLASSES}
instead.
*/
- String FLAG_CLASS_PATH_CONSTITUENT = "classPathConstituent";
+ @Deprecated
+ Key<Boolean> FLAG_CLASS_PATH_CONSTITUENT = new
Key<>("classPathConstituent", Boolean.class).intern();
/**
- * Returns immutable "map view" of all the properties.
+ * {@return the keys of all properties in this map}.
*/
- @Nonnull
- Map<String, String> asMap();
+ Set<Key<?>> keys();
+
+ /**
+ * Returns the value associated to the given key.
+ *
+ * @param <V> type of value to get
+ * @param key key of the value to get
+ * @return value associated to the given key, or {@code null} if none
+ */
+ <V> V get(@Nonnull Key<V> key);
+
+ /**
+ * Returns the value associated to the given key, or the given default
value if none.
+ *
+ * @param <V> type of value to get
+ * @param key key of the value to get
+ * @param defaultValue the value to return is none is associated to the
given key, or {@code null}
+ * @return value associated to the given key, or {@code null} if none and
the default is null
+ */
+ <V> V getOrDefault(@Nonnull Key<V> key, V defaultValue);
Review Comment:
Missing `@Nullable` on the return value and the `V` parameter to be explicit
.
##########
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java:
##########
@@ -33,27 +36,226 @@
@Immutable
public interface DependencyProperties {
/**
- * Boolean flag telling that dependency contains all of its dependencies.
Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Keys in the dependency properties map.
+ * Each key can be associated to values of a specific class.
+ *
+ * @param <V> type of value associated to the key
+ */
+ class Key<V> {
+ /**
+ * The keys that are defined in this {@code DependencyProperties} map.
+ * Accesses to this map shall be synchronized on the map.
+ *
+ * @see #intern()
+ */
+ private static final Map<String, Key<?>> INTERNS = new HashMap<>();
+
+ /**
+ * Value returned by {@link #name()}.
+ */
+ @Nonnull
+ private final String name;
+
+ /**
+ * Value returned by {@link #valueType()}.
+ */
+ @Nonnull
+ private final Class<V> valueType;
+
+ /**
+ * Creates a new key.
+ *
+ * @param name name of the key
+ * @param valueType type of value associated to the key
+ */
+ public Key(@Nonnull final String name, @Nonnull final Class<V>
valueType) {
Review Comment:
`final` in parameters is useless, please remove
##########
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java:
##########
@@ -33,27 +36,226 @@
@Immutable
public interface DependencyProperties {
/**
- * Boolean flag telling that dependency contains all of its dependencies.
Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Keys in the dependency properties map.
+ * Each key can be associated to values of a specific class.
+ *
+ * @param <V> type of value associated to the key
+ */
+ class Key<V> {
+ /**
+ * The keys that are defined in this {@code DependencyProperties} map.
+ * Accesses to this map shall be synchronized on the map.
+ *
+ * @see #intern()
+ */
+ private static final Map<String, Key<?>> INTERNS = new HashMap<>();
+
+ /**
+ * Value returned by {@link #name()}.
+ */
+ @Nonnull
+ private final String name;
+
+ /**
+ * Value returned by {@link #valueType()}.
+ */
+ @Nonnull
+ private final Class<V> valueType;
+
+ /**
+ * Creates a new key.
+ *
+ * @param name name of the key
+ * @param valueType type of value associated to the key
+ */
+ public Key(@Nonnull final String name, @Nonnull final Class<V>
valueType) {
+ this.name = Objects.requireNonNull(name);
+ this.valueType = Objects.requireNonNull(valueType);
+ }
+
+ /**
+ * If a key exists in the {@linkplain #intern() intern pool} for the
given name, returns that key.
+ * Otherwise, if the {@code defaultType} is non-null, creates a key
for values of the specified type.
+ * Otherwise, returns {@code null}.
+ *
+ * @param name name of the key to search or create
+ * @param defaultType value type of the key to create if none exist
for the given name, or {@code null}
+ * @return key found or created, or {@code null} if no key was found
and {@code defaultType} is null
+ *
+ * @see #intern()
+ */
+ public static Key<?> forName(String name, Class<?> defaultType) {
+ Key<?> key;
+ synchronized (INTERNS) {
+ key = INTERNS.get(name);
+ }
+ if (key == null && defaultType != null) {
+ key = new Key<>(name, defaultType);
+ }
+ return key;
+ }
+
+ /**
+ * {@return the name of the key}.
+ */
+ @Nonnull
+ public String name() {
+ return name;
+ }
+
+ /**
+ * {@return the type of value associated to the key}.
+ */
+ @Nonnull
+ public Class<V> valueType() {
+ return valueType;
+ }
+
+ /**
+ * {@return a canonical representation of this key}. A pool of keys,
initially empty, is maintained privately.
+ * When the {@code intern()} method is invoked, if the pool already
contains a key equal to this {@code Key}
+ * as determined by the {@link #equals(Object)} method, then the key
from the pool is returned. Otherwise,
+ * if no key exist in the pool for this key {@linkplain #name() name},
then this {@code Key} object is added
+ * to the pool and {@code this} is returned. Otherwise an {@link
IllegalStateException} is thrown.
+ *
+ * @throws IllegalStateException if a key exists in the pool for the
same name but a different class of values.
+ *
+ * @see String#intern()
+ */
+ @SuppressWarnings("unchecked")
+ public Key<V> intern() {
Review Comment:
I don't think the whole `intern` thing is needed at all.
I would suppose all references to `Key`s will be done using
`DependencyProperties.XXX`, so I don't see a good use case for users to create
duplicate instances.
##########
api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java:
##########
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.StringJoiner;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * The option of a Java command-line tool where to place the paths to some
dependencies.
+ * A {@code PathType} can identify the class-path, the module-path, the
patches for a specific module,
+ * or another kind of path. This class is like an enumeration, except that it
is extensible:
+ * plugins can define their own kinds of path.
+ *
+ * <p>One path type is handled in a special way: contrarily to other options,
+ * the paths specified in a {@code --patch-module} Java option is effective
only for a specified module.
+ * This type is created by calls to {@link #patchModule(String)} and a new
instance must be created for
+ * every module to patch.</p>
+ *
+ * <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>
+ *
+ * @see
org.apache.maven.api.services.DependencyResolverResult#getDispatchedPaths()
+ *
+ * @since 4.0.0
+ */
+@Experimental
+public final class JavaPathType extends PathType {
+ /**
+ * The path identified by the Java {@code --class-path} option.
+ * Used for compilation, execution and Javadoc among others.
+ *
+ * <h4>Context-sensitive interpretation</h4>
+ * A dependency with this path type will not necessarily be placed on the
class-path.
+ * There is two circumstances where the dependency may be nevertheless
placed somewhere else:
Review Comment:
`There is` -> `There are`
`be nevertheless` -> `nevertheless be`
##########
api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java:
##########
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.StringJoiner;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * The option of a Java command-line tool where to place the paths to some
dependencies.
+ * A {@code PathType} can identify the class-path, the module-path, the
patches for a specific module,
+ * or another kind of path. This class is like an enumeration, except that it
is extensible:
+ * plugins can define their own kinds of path.
+ *
+ * <p>One path type is handled in a special way: contrarily to other options,
+ * the paths specified in a {@code --patch-module} Java option is effective
only for a specified module.
+ * This type is created by calls to {@link #patchModule(String)} and a new
instance must be created for
+ * every module to patch.</p>
+ *
+ * <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>
+ *
+ * @see
org.apache.maven.api.services.DependencyResolverResult#getDispatchedPaths()
+ *
+ * @since 4.0.0
+ */
+@Experimental
+public final class JavaPathType extends PathType {
+ /**
+ * The path identified by the Java {@code --class-path} option.
+ * Used for compilation, execution and Javadoc among others.
+ *
+ * <h4>Context-sensitive interpretation</h4>
+ * A dependency with this path type will not necessarily be placed on the
class-path.
+ * There is two circumstances where the dependency may be nevertheless
placed somewhere else:
+ *
+ * <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,
+ * possibly using heuristic rules (Maven 3 behavior).</li>
+ * <li>If a {@link #patchModule(String)} is also set and the main JAR
file was placed on the module-path,
Review Comment:
`was placed` -> `is placed`
##########
api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java:
##########
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.StringJoiner;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * The option of a Java command-line tool where to place the paths to some
dependencies.
+ * A {@code PathType} can identify the class-path, the module-path, the
patches for a specific module,
+ * or another kind of path. This class is like an enumeration, except that it
is extensible:
+ * plugins can define their own kinds of path.
+ *
+ * <p>One path type is handled in a special way: contrarily to other options,
Review Comment:
`contrarily to` -> `unlike`
##########
api/maven-api-core/src/main/java/org/apache/maven/api/Type.java:
##########
@@ -80,11 +129,16 @@ public interface Type {
String getClassifier();
/**
- * Specifies if the artifact contains java classes and should be
- * added to the classpath.
+ * Specifies if the artifact contains java classes and can be added to the
classpath.
+ * Whether the artifact <em>should</em> be added to the classpath depends
on other
+ * {@linkplain #getDependencyProperties() dependency properties}.
+ *
+ * @return if the artifact <em>can</em> be added to the class path
*
- * @return if the artifact should be added to the class path
+ * @deprecated A value of {@code true} does not mean that the dependency
<em>should</em>
+ * be placed on the classpath. See {@link JavaPathType} instead for better
analysis.
*/
+ @Deprecated
Review Comment:
If deprecation is necessary, it should be noted that it will be removed
before 4.0.0 GA.
##########
api/maven-api-core/src/main/java/org/apache/maven/api/PathType.java:
##########
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * The option of a command-line tool where to place the paths to some
dependencies.
+ * A {@code PathType} can identify the Java class-path, the Java module-path,
+ * or another kind of path for another programming language for example.
+ * This class is like an enumeration, except that it is extensible:
+ * plugins can define their own kinds of path.
+ *
+ * <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>
+ *
+ * @see DependencyProperties#PATH_TYPES
+ * @see
org.apache.maven.api.services.DependencyResolverResult#getDispatchedPaths()
+ *
+ * @since 4.0.0
+ */
+@Experimental
+public abstract class PathType {
Review Comment:
I'm not convinced we will ever have an implementation other than
`JavaPathType`, in which case, both interfaces could be merged. I'd also
prefer an interface rather than an abstract class if that's possible.
##########
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java:
##########
@@ -33,27 +36,226 @@
@Immutable
public interface DependencyProperties {
/**
- * Boolean flag telling that dependency contains all of its dependencies.
Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Keys in the dependency properties map.
+ * Each key can be associated to values of a specific class.
+ *
+ * @param <V> type of value associated to the key
+ */
+ class Key<V> {
+ /**
+ * The keys that are defined in this {@code DependencyProperties} map.
+ * Accesses to this map shall be synchronized on the map.
+ *
+ * @see #intern()
+ */
+ private static final Map<String, Key<?>> INTERNS = new HashMap<>();
+
+ /**
+ * Value returned by {@link #name()}.
+ */
+ @Nonnull
+ private final String name;
+
+ /**
+ * Value returned by {@link #valueType()}.
+ */
+ @Nonnull
+ private final Class<V> valueType;
+
+ /**
+ * Creates a new key.
+ *
+ * @param name name of the key
+ * @param valueType type of value associated to the key
+ */
+ public Key(@Nonnull final String name, @Nonnull final Class<V>
valueType) {
+ this.name = Objects.requireNonNull(name);
+ this.valueType = Objects.requireNonNull(valueType);
+ }
+
+ /**
+ * If a key exists in the {@linkplain #intern() intern pool} for the
given name, returns that key.
+ * Otherwise, if the {@code defaultType} is non-null, creates a key
for values of the specified type.
+ * Otherwise, returns {@code null}.
+ *
+ * @param name name of the key to search or create
+ * @param defaultType value type of the key to create if none exist
for the given name, or {@code null}
+ * @return key found or created, or {@code null} if no key was found
and {@code defaultType} is null
+ *
+ * @see #intern()
+ */
+ public static Key<?> forName(String name, Class<?> defaultType) {
+ Key<?> key;
+ synchronized (INTERNS) {
+ key = INTERNS.get(name);
+ }
+ if (key == null && defaultType != null) {
+ key = new Key<>(name, defaultType);
+ }
+ return key;
+ }
+
+ /**
+ * {@return the name of the key}.
+ */
+ @Nonnull
+ public String name() {
+ return name;
+ }
+
+ /**
+ * {@return the type of value associated to the key}.
+ */
+ @Nonnull
+ public Class<V> valueType() {
+ return valueType;
+ }
+
+ /**
+ * {@return a canonical representation of this key}. A pool of keys,
initially empty, is maintained privately.
+ * When the {@code intern()} method is invoked, if the pool already
contains a key equal to this {@code Key}
+ * as determined by the {@link #equals(Object)} method, then the key
from the pool is returned. Otherwise,
+ * if no key exist in the pool for this key {@linkplain #name() name},
then this {@code Key} object is added
+ * to the pool and {@code this} is returned. Otherwise an {@link
IllegalStateException} is thrown.
+ *
+ * @throws IllegalStateException if a key exists in the pool for the
same name but a different class of values.
+ *
+ * @see String#intern()
+ */
+ @SuppressWarnings("unchecked")
+ public Key<V> intern() {
+ Key<?> previous;
+ synchronized (INTERNS) {
+ previous = INTERNS.putIfAbsent(name, this);
+ }
+ if (previous == null) {
+ return this;
+ }
+ if (equals(previous)) {
+ return (Key<V>) previous;
+ }
+ throw new IllegalStateException("Key " + name + " already exists
for a different class of values.");
+ }
+
+ /**
+ * {@return a string representation of this key}.
+ * By default, this is the name of this key.
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * {@return an hash code value for this key}.
+ */
+ @Override
+ public int hashCode() {
+ return 7 + name.hashCode() + 31 * valueType.hashCode();
+ }
+
+ /**
+ * Compares this key with the given object for equality.
+ * Two keys are considered equal if they have the same name
+ * and are associated to values of the same class.
+ *
+ * @param obj the object to compare with this key
+ * @return whether the given object is equal to this key
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj != null && getClass() == obj.getClass()) {
+ final Key<?> other = (Key<?>) obj;
+ return name.equals(other.name) &&
valueType.equals(other.valueType);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * The dependency type. The {@linkplain Key#name() name} of this property
+ * is equal to the {@code ArtifactProperties.TYPE} value.
+ */
+ Key<String> TYPE = new Key<>("type", String.class).intern();
+
+ /**
+ * The dependency language. The {@linkplain Key#name() name} of this
property
+ * is equal to the {@code ArtifactProperties.LANGUAGE} value.
+ */
+ Key<String> LANGUAGE = new Key<>("language", String.class).intern();
+
+ /**
+ * Types of path (class-path, module-path, …) where the dependency can be
placed.
+ * For most deterministic builds, the array length should be 1. In such
case,
+ * the dependency will be unconditionally placed on the specified type of
path
+ * and no heuristic rule will be involved.
+ *
+ * <p>It is nevertheless common to specify two or more types of path. For
example,
+ * a Java library may be compatible with either the class-path or the
module-path,
+ * and the user may have provided no instruction about which type to use.
In such
+ * case, the plugin may apply rules for choosing a path. See for example
+ * {@link JavaPathType#CLASSES} and {@link JavaPathType#MODULES}.</p>
+ */
+ Key<PathType[]> PATH_TYPES = new Key<>("pathTypes",
PathType[].class).intern();
Review Comment:
`Collection<PathType>` so that we can ensure immutability ?
##########
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java:
##########
@@ -33,27 +36,226 @@
@Immutable
public interface DependencyProperties {
/**
- * Boolean flag telling that dependency contains all of its dependencies.
Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Keys in the dependency properties map.
+ * Each key can be associated to values of a specific class.
+ *
+ * @param <V> type of value associated to the key
+ */
+ class Key<V> {
+ /**
+ * The keys that are defined in this {@code DependencyProperties} map.
+ * Accesses to this map shall be synchronized on the map.
+ *
+ * @see #intern()
+ */
+ private static final Map<String, Key<?>> INTERNS = new HashMap<>();
+
+ /**
+ * Value returned by {@link #name()}.
+ */
+ @Nonnull
+ private final String name;
+
+ /**
+ * Value returned by {@link #valueType()}.
+ */
+ @Nonnull
+ private final Class<V> valueType;
+
+ /**
+ * Creates a new key.
+ *
+ * @param name name of the key
+ * @param valueType type of value associated to the key
+ */
+ public Key(@Nonnull final String name, @Nonnull final Class<V>
valueType) {
+ this.name = Objects.requireNonNull(name);
+ this.valueType = Objects.requireNonNull(valueType);
+ }
+
+ /**
+ * If a key exists in the {@linkplain #intern() intern pool} for the
given name, returns that key.
+ * Otherwise, if the {@code defaultType} is non-null, creates a key
for values of the specified type.
+ * Otherwise, returns {@code null}.
+ *
+ * @param name name of the key to search or create
+ * @param defaultType value type of the key to create if none exist
for the given name, or {@code null}
+ * @return key found or created, or {@code null} if no key was found
and {@code defaultType} is null
+ *
+ * @see #intern()
+ */
+ public static Key<?> forName(String name, Class<?> defaultType) {
+ Key<?> key;
+ synchronized (INTERNS) {
+ key = INTERNS.get(name);
+ }
+ if (key == null && defaultType != null) {
+ key = new Key<>(name, defaultType);
+ }
+ return key;
+ }
+
+ /**
+ * {@return the name of the key}.
+ */
+ @Nonnull
+ public String name() {
+ return name;
+ }
+
+ /**
+ * {@return the type of value associated to the key}.
+ */
+ @Nonnull
+ public Class<V> valueType() {
+ return valueType;
+ }
+
+ /**
+ * {@return a canonical representation of this key}. A pool of keys,
initially empty, is maintained privately.
+ * When the {@code intern()} method is invoked, if the pool already
contains a key equal to this {@code Key}
+ * as determined by the {@link #equals(Object)} method, then the key
from the pool is returned. Otherwise,
+ * if no key exist in the pool for this key {@linkplain #name() name},
then this {@code Key} object is added
+ * to the pool and {@code this} is returned. Otherwise an {@link
IllegalStateException} is thrown.
+ *
+ * @throws IllegalStateException if a key exists in the pool for the
same name but a different class of values.
+ *
+ * @see String#intern()
+ */
+ @SuppressWarnings("unchecked")
+ public Key<V> intern() {
+ Key<?> previous;
+ synchronized (INTERNS) {
+ previous = INTERNS.putIfAbsent(name, this);
+ }
+ if (previous == null) {
+ return this;
+ }
+ if (equals(previous)) {
+ return (Key<V>) previous;
+ }
+ throw new IllegalStateException("Key " + name + " already exists
for a different class of values.");
+ }
+
+ /**
+ * {@return a string representation of this key}.
+ * By default, this is the name of this key.
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * {@return an hash code value for this key}.
+ */
+ @Override
+ public int hashCode() {
+ return 7 + name.hashCode() + 31 * valueType.hashCode();
+ }
+
+ /**
+ * Compares this key with the given object for equality.
+ * Two keys are considered equal if they have the same name
+ * and are associated to values of the same class.
+ *
+ * @param obj the object to compare with this key
+ * @return whether the given object is equal to this key
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj != null && getClass() == obj.getClass()) {
+ final Key<?> other = (Key<?>) obj;
+ return name.equals(other.name) &&
valueType.equals(other.valueType);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * The dependency type. The {@linkplain Key#name() name} of this property
+ * is equal to the {@code ArtifactProperties.TYPE} value.
+ */
+ Key<String> TYPE = new Key<>("type", String.class).intern();
+
+ /**
+ * The dependency language. The {@linkplain Key#name() name} of this
property
+ * is equal to the {@code ArtifactProperties.LANGUAGE} value.
+ */
+ Key<String> LANGUAGE = new Key<>("language", String.class).intern();
+
+ /**
+ * Types of path (class-path, module-path, …) where the dependency can be
placed.
+ * For most deterministic builds, the array length should be 1. In such
case,
+ * the dependency will be unconditionally placed on the specified type of
path
+ * and no heuristic rule will be involved.
+ *
+ * <p>It is nevertheless common to specify two or more types of path. For
example,
+ * a Java library may be compatible with either the class-path or the
module-path,
+ * and the user may have provided no instruction about which type to use.
In such
+ * case, the plugin may apply rules for choosing a path. See for example
+ * {@link JavaPathType#CLASSES} and {@link JavaPathType#MODULES}.</p>
+ */
+ Key<PathType[]> PATH_TYPES = new Key<>("pathTypes",
PathType[].class).intern();
+
+ /**
+ * Boolean flag telling that dependency contains all of its dependencies.
* <p>
* <em>Important: this flag must be kept in sync with resolver! (as is
used during collection)</em>
*/
- String FLAG_INCLUDES_DEPENDENCIES = "includesDependencies";
+ Key<Boolean> FLAG_INCLUDES_DEPENDENCIES = new
Key<>("includesDependencies", Boolean.class).intern();
/**
- * Boolean flag telling that dependency is meant to be placed on class
path. Value of this key should be parsed with
- * {@link Boolean#parseBoolean(String)} to obtain value.
+ * Boolean flag telling that dependency is meant to be placed on class
path.
+ *
+ * @deprecated Use {@link #PATH_TYPES} and {@link JavaPathType#CLASSES}
instead.
*/
- String FLAG_CLASS_PATH_CONSTITUENT = "classPathConstituent";
+ @Deprecated
+ Key<Boolean> FLAG_CLASS_PATH_CONSTITUENT = new
Key<>("classPathConstituent", Boolean.class).intern();
/**
- * Returns immutable "map view" of all the properties.
+ * {@return the keys of all properties in this map}.
*/
- @Nonnull
- Map<String, String> asMap();
+ Set<Key<?>> keys();
+
+ /**
+ * Returns the value associated to the given key.
+ *
+ * @param <V> type of value to get
+ * @param key key of the value to get
+ * @return value associated to the given key, or {@code null} if none
+ */
+ <V> V get(@Nonnull Key<V> key);
Review Comment:
`Optional<V>` as a return value ?
##########
api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java:
##########
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.StringJoiner;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * The option of a Java command-line tool where to place the paths to some
dependencies.
+ * A {@code PathType} can identify the class-path, the module-path, the
patches for a specific module,
+ * or another kind of path. This class is like an enumeration, except that it
is extensible:
+ * plugins can define their own kinds of path.
+ *
+ * <p>One path type is handled in a special way: contrarily to other options,
+ * the paths specified in a {@code --patch-module} Java option is effective
only for a specified module.
+ * This type is created by calls to {@link #patchModule(String)} and a new
instance must be created for
+ * every module to patch.</p>
+ *
+ * <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>
+ *
+ * @see
org.apache.maven.api.services.DependencyResolverResult#getDispatchedPaths()
+ *
+ * @since 4.0.0
+ */
+@Experimental
+public final class JavaPathType extends PathType {
+ /**
+ * The path identified by the Java {@code --class-path} option.
+ * Used for compilation, execution and Javadoc among others.
+ *
+ * <h4>Context-sensitive interpretation</h4>
+ * A dependency with this path type will not necessarily be placed on the
class-path.
+ * There is two circumstances where the dependency may be nevertheless
placed somewhere else:
+ *
+ * <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,
+ * possibly using heuristic rules (Maven 3 behavior).</li>
+ * <li>If a {@link #patchModule(String)} is also set and the main JAR
file was placed on the module-path,
+ * then the test dependency will be placed on the Java {@code
--patch-module} option instead of the
+ * class-path.</li>
+ * </ul>
+ */
+ public static final JavaPathType CLASSES = new JavaPathType("CLASSES",
"--class-path", null);
+
+ /**
+ * The path identified by the Java {@code --module-path} option.
+ * Used for compilation, execution and Javadoc among others.
+ *
+ * <h4>Context-sensitive interpretation</h4>
+ * A dependency with this flag will not necessarily be placed on the
module-path.
+ * There is two circumstances where the dependency may be nevertheless
placed somewhere else:
+ *
+ * <ul>
+ * <li>If {@link #CLASSES} path type is also set, then the dependency
<em>should</em> be placed on the
+ * module-path, but is nevertheless compatible with placement on the
class-path. Compatibility can
+ * be achieved, for example, by repeating in the {@code
META-INF/services/} directory the services
+ * that are declared in the {@code module-info.class} file. In that
case, the path type can be chosen
+ * by the plugin.</li>
+ * <li>If a {@link #patchModule(String)} is also set and the main JAR
file was placed on the module-path,
+ * then the test dependency will be placed on the Java {@code
--patch-module} option instead of the
+ * module-path.</li>
Review Comment:
`module-path` -> `{@code --module-path}` for consistency
##########
api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java:
##########
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.StringJoiner;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * The option of a Java command-line tool where to place the paths to some
dependencies.
+ * A {@code PathType} can identify the class-path, the module-path, the
patches for a specific module,
+ * or another kind of path. This class is like an enumeration, except that it
is extensible:
+ * plugins can define their own kinds of path.
+ *
+ * <p>One path type is handled in a special way: contrarily to other options,
+ * the paths specified in a {@code --patch-module} Java option is effective
only for a specified module.
+ * This type is created by calls to {@link #patchModule(String)} and a new
instance must be created for
+ * every module to patch.</p>
+ *
+ * <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>
+ *
+ * @see
org.apache.maven.api.services.DependencyResolverResult#getDispatchedPaths()
+ *
+ * @since 4.0.0
+ */
+@Experimental
+public final class JavaPathType extends PathType {
+ /**
+ * The path identified by the Java {@code --class-path} option.
+ * Used for compilation, execution and Javadoc among others.
+ *
+ * <h4>Context-sensitive interpretation</h4>
+ * A dependency with this path type will not necessarily be placed on the
class-path.
+ * There is two circumstances where the dependency may be nevertheless
placed somewhere else:
+ *
+ * <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,
+ * possibly using heuristic rules (Maven 3 behavior).</li>
+ * <li>If a {@link #patchModule(String)} is also set and the main JAR
file was placed on the module-path,
+ * then the test dependency will be placed on the Java {@code
--patch-module} option instead of the
+ * class-path.</li>
+ * </ul>
+ */
+ public static final JavaPathType CLASSES = new JavaPathType("CLASSES",
"--class-path", null);
+
+ /**
+ * The path identified by the Java {@code --module-path} option.
+ * Used for compilation, execution and Javadoc among others.
+ *
+ * <h4>Context-sensitive interpretation</h4>
+ * A dependency with this flag will not necessarily be placed on the
module-path.
+ * There is two circumstances where the dependency may be nevertheless
placed somewhere else:
Review Comment:
`There is` -> `There are`
`be nevertheless` -> `nevertheless be`
> Control the type of path where each dependency can be placed
> ------------------------------------------------------------
>
> Key: MNG-8015
> URL: https://issues.apache.org/jira/browse/MNG-8015
> Project: Maven
> Issue Type: Improvement
> Components: Core
> Affects Versions: 4.0.0-alpha-12
> Reporter: Martin Desruisseaux
> Priority: Major
>
> Make possible to declare where each dependency can be placed: on the
> module-path, class-path, agent path, doclet path, taglet path, annotation
> processing path, _etc._ The proposed improvement consists in adding a new
> {{PATH_TYPES}} property that can be associated to dependencies. The property
> value is an array of {{PathType}}, a new enumeration-like class with values
> such as {{CLASSES}}, {{MODULES}}, {{DOCLET}}, _etc._ Contrarily to real Java
> enumerations, this enumeration-like class is extensible: plugins can add
> their own enumeration values. This is required at least for the
> {{--patch-module}} option, where a new {{PathType}} enumeration value need to
> be created for each module to patch.
> Users can control indirectly the {{PathType}} of a dependency by specifying
> the dependency type. Note that there is no direct mapping between the
> dependency type and where the dependency will be placed, but only an indirect
> mapping caused by the fact that using a dependency type implies implicit
> values of some properties such as classifier, and (with this proposal) path
> types:
> * {{<type>jar</type>}} implies {{PathType.CLASSES}} and {{PathType.MODULES}}.
> * {{<type>modular-jar</type>}} implies {{PathType.MODULES}} only.
> * {{<type>classpath-jar</type>}} implies {{PathType.CLASSES}} only.
> * _etc._
> When a plugin requests the paths of dependencies, the plugin specifies the
> types of path it is interested in. For example, a Java compiler plugin can
> specify that it is interested in {{PathType.CLASSES}} and
> {{PathType.MODULES}}, but not {{PathType.DOCLET}}. If a dependency declared
> that it can be placed on the class-path or the doclet-path, only the
> class-path is left after intersection with plugin's request. This is
> important for the next step.
> If, after all filtering such as above paragraph are applied, a dependency has
> only one {{PathType}} left, then there is no ambiguity and we are done.
> Combined with above-cited dependency types like {{modular-jar}} or
> {{classpath-jar}}, this rule allows users to control where the dependency
> will be placed. But if there are two or more {{PathType}} left after
> filtering, then a choice needs to be done. For example if there are both
> {{PathType.CLASSES}} and {{PathType.MODULES}} (which may happen when
> {{<type>jar</type>}} is used), then an heuristic rule similar to Maven 3 can
> be applied: check if a {{module-info.class}} file or an {{Automatic-Name}}
> manifest attribute is present, and base the decision on that.
> This proposal aims to fix MNG-7855.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)