desruisseaux commented on code in PR #1378: URL: https://github.com/apache/maven/pull/1378#discussion_r1460410367
########## 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: Actually the above code does not fit exactly the `DefaultDependencies` needs, because it forces the key to be of the type specified by `defaultType`. This is the correct thing to do for above method because its return value is `Key<T>`. However, `DefaultDependencies` needs to first check for a key with whatever type an existing key may have. So we cannot escape the need to have two methods, one with return value `Key<?>` and another one with return value `Key<V>`. I will replace the existing `forName` method with a simpler one like below, checking only for existing key: ``` Optional<Key<?>> forName(String); ``` As a replacement of `intern()`, I considered adding the following method: ``` <V> Key<V> createAndCache(String name, Class<V> valueType); ``` However it would not work if some plugin wants to define its own subclass of `Key`, while `intern()` allows this flexibility. I'm not sure if it is a flexibility worth to have however. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@maven.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org