[
https://issues.apache.org/jira/browse/MNG-8015?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17808674#comment-17808674
]
ASF GitHub Bot commented on MNG-8015:
-------------------------------------
gnodet commented on code in PR #1378:
URL: https://github.com/apache/maven/pull/1378#discussion_r1459072073
##########
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:
Would it make sense to remove the `intern()` method and redefine `forName`
as:
```
@Nullable
public static <T> Key<T> forName(@Nonnull String name, @Nullable
Class<T> defaultType, boolean intern) {
Key<?> key;
synchronized (INTERNS) {
key = INTERNS.get(name);
if (defaultType != null) {
if (key == null) {
key = new Key<>(name, defaultType);
if (intern) {
INTERNS.put(name, key);
}
} else if (key.valueType() != defaultType && intern) {
throw new IllegalStateException("Key " + name + "
already exists for a different class of values.");
}
}
}
return (Key) key;
}
```
The constructor could be made `private`, so that the only entry point is the
above method.
> 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)