[ 
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)

Reply via email to