This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/maven-4.0.x by this push:
     new aec75941db Add InputLocation/InputSource factory methods and make 
classes final for 4.0.0-rc-6 (#11538)
aec75941db is described below

commit aec75941db1387efae3fe381519fdc3bfb24a61e
Author: Guillaume Nodet <[email protected]>
AuthorDate: Fri Dec 12 17:05:09 2025 +0100

    Add InputLocation/InputSource factory methods and make classes final for 
4.0.0-rc-6 (#11538)
    
    This commit addresses API compatibility issues introduced in commit 
731700abc62808ce7ab8aad64323ed16e9950516 on master (4.1.0-SNAPSHOT), which made 
InputLocation constructors package-private and added static factory methods. 
Since Maven 4.0 hasn't been released yet, we're backporting these changes in a 
backward-compatible way.
    
    Changes:
    - Added static factory methods of(...) to InputLocation and InputSource 
classes
    - Deprecated all constructors with 'since 4.0.0-rc-6' message
    - Made both InputLocation and InputSource classes final to prevent extension
    - Updated internal Maven code to use factory methods instead of constructors
    - Applied changes to both hand-written files and Modello templates
    
    The constructors remain public (just deprecated) to maintain compatibility 
with extensions like mason, while the final modifier prevents subclassing which 
would break in 4.1.0 anyway.
    
    This ensures consistency between 4.0.0-rc-6 and 4.1.0-SNAPSHOT while 
maintaining backward compatibility for existing code.
---
 .../org/apache/maven/api/model/InputLocation.java  | 159 ++++++++++++++++++++-
 .../org/apache/maven/api/model/InputSource.java    |   2 +-
 .../java/org/apache/maven/model/InputLocation.java |   6 +-
 .../org/apache/maven/impl/SettingsUtilsV4.java     |   2 +-
 src/mdo/java/InputLocation.java                    | 159 ++++++++++++++++++++-
 src/mdo/java/InputSource.java                      |   2 +-
 6 files changed, 317 insertions(+), 13 deletions(-)

diff --git 
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocation.java
 
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocation.java
index cde5c51b23..9ecfb400ff 100644
--- 
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocation.java
+++ 
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputLocation.java
@@ -31,16 +31,28 @@
  * This class tracks the line and column numbers of elements in source files 
like POM files.
  * It's used for error reporting and debugging to help identify where specific 
model elements
  * are defined in the source files.
+ * <p>
+ * Note: Starting with Maven 4.0.0, it is recommended to use the static 
factory methods
+ * {@code of(...)} instead of constructors. The constructors are deprecated 
and will be
+ * removed in a future version.
  *
  * @since 4.0.0
  */
-public class InputLocation implements Serializable, InputLocationTracker {
+public final class InputLocation implements Serializable, InputLocationTracker 
{
     private final int lineNumber;
     private final int columnNumber;
     private final InputSource source;
     private final Map<Object, InputLocation> locations;
     private final InputLocation importedFrom;
 
+    /**
+     * Creates an InputLocation with only a source, no line/column information.
+     * The line and column numbers will be set to -1 (unknown).
+     *
+     * @param source the input source where this location originates from
+     * @deprecated since 4.0.0-rc-6, use {@link #of(InputSource)} instead
+     */
+    @Deprecated
     public InputLocation(InputSource source) {
         this.lineNumber = -1;
         this.columnNumber = -1;
@@ -49,14 +61,41 @@ public InputLocation(InputSource source) {
         this.importedFrom = null;
     }
 
+    /**
+     * Creates an InputLocation with line and column numbers but no source.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @deprecated since 4.0.0-rc-6, use {@link #of(int, int)} instead
+     */
+    @Deprecated
     public InputLocation(int lineNumber, int columnNumber) {
         this(lineNumber, columnNumber, null, null);
     }
 
+    /**
+     * Creates an InputLocation with line number, column number, and source.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @deprecated since 4.0.0-rc-6, use {@link #of(int, int, InputSource)} 
instead
+     */
+    @Deprecated
     public InputLocation(int lineNumber, int columnNumber, InputSource source) 
{
         this(lineNumber, columnNumber, source, null);
     }
 
+    /**
+     * Creates an InputLocation with line number, column number, source, and a 
self-location key.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @param selfLocationKey the key to map this location to itself in the 
locations map
+     * @deprecated since 4.0.0-rc-6, use {@link #of(int, int, InputSource, 
Object)} instead
+     */
+    @Deprecated
     public InputLocation(int lineNumber, int columnNumber, InputSource source, 
Object selfLocationKey) {
         this.lineNumber = lineNumber;
         this.columnNumber = columnNumber;
@@ -66,6 +105,16 @@ public InputLocation(int lineNumber, int columnNumber, 
InputSource source, Objec
         this.importedFrom = null;
     }
 
+    /**
+     * Creates an InputLocation with line number, column number, source, and a 
complete locations map.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @param locations a map of keys to InputLocation instances for nested 
elements
+     * @deprecated since 4.0.0-rc-6, use {@link #of(int, int, InputSource, 
Map)} instead
+     */
+    @Deprecated
     public InputLocation(int lineNumber, int columnNumber, InputSource source, 
Map<Object, InputLocation> locations) {
         this.lineNumber = lineNumber;
         this.columnNumber = columnNumber;
@@ -74,6 +123,13 @@ public InputLocation(int lineNumber, int columnNumber, 
InputSource source, Map<O
         this.importedFrom = null;
     }
 
+    /**
+     * Creates a copy of an existing InputLocation.
+     *
+     * @param original the InputLocation to copy
+     * @deprecated since 4.0.0-rc-6, use the original instance directly as 
InputLocation is immutable
+     */
+    @Deprecated
     public InputLocation(InputLocation original) {
         this.lineNumber = original.lineNumber;
         this.columnNumber = original.columnNumber;
@@ -82,24 +138,121 @@ public InputLocation(InputLocation original) {
         this.importedFrom = original.importedFrom;
     }
 
+    /**
+     * Creates an InputLocation with the specified source.
+     *
+     * @param source the input source
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(InputSource source) {
+        return new InputLocation(source);
+    }
+
+    /**
+     * Creates an InputLocation with the specified line and column numbers.
+     * The source and locations map will be null.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(int lineNumber, int columnNumber) {
+        return new InputLocation(lineNumber, columnNumber);
+    }
+
+    /**
+     * Creates an InputLocation with the specified line number, column number, 
and source.
+     * The locations map will be empty.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(int lineNumber, int columnNumber, 
InputSource source) {
+        return new InputLocation(lineNumber, columnNumber, source);
+    }
+
+    /**
+     * Creates an InputLocation with the specified line number, column number, 
source,
+     * and a self-location key. The locations map will contain a single entry 
mapping
+     * the selfLocationKey to this location.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @param selfLocationKey the key to map this location to itself in the 
locations map
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(int lineNumber, int columnNumber, 
InputSource source, Object selfLocationKey) {
+        return new InputLocation(lineNumber, columnNumber, source, 
selfLocationKey);
+    }
+
+    /**
+     * Creates an InputLocation with the specified line number, column number, 
source,
+     * and a complete locations map. This is typically used when merging or 
combining
+     * location information from multiple sources.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @param locations a map of keys to InputLocation instances for nested 
elements
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(
+            int lineNumber, int columnNumber, InputSource source, Map<Object, 
InputLocation> locations) {
+        return new InputLocation(lineNumber, columnNumber, source, locations);
+    }
+
+    /**
+     * Gets the one-based line number where this element is located in the 
source file.
+     *
+     * @return the line number, or -1 if unknown
+     */
     public int getLineNumber() {
         return lineNumber;
     }
 
+    /**
+     * Gets the one-based column number where this element is located in the 
source file.
+     *
+     * @return the column number, or -1 if unknown
+     */
     public int getColumnNumber() {
         return columnNumber;
     }
 
+    /**
+     * Gets the input source where this location originates from.
+     *
+     * @return the input source, or null if unknown
+     */
     public InputSource getSource() {
         return source;
     }
 
+    /**
+     * Gets the InputLocation for a specific nested element key.
+     *
+     * @param key the key to look up
+     * @return the InputLocation for the specified key, or null if not found
+     */
     @Override
     public InputLocation getLocation(Object key) {
         Objects.requireNonNull(key, "key");
         return locations != null ? locations.get(key) : null;
     }
 
+    /**
+     * Gets the map of nested element locations within this location.
+     *
+     * @return an immutable map of keys to InputLocation instances for nested 
elements
+     */
     public Map<Object, InputLocation> getLocations() {
         return locations;
     }
@@ -144,7 +297,7 @@ public static InputLocation merge(InputLocation target, 
InputLocation source, bo
             locations.putAll(sourceDominant ? sourceLocations : 
targetLocations);
         }
 
-        return new InputLocation(-1, -1, InputSource.merge(source.getSource(), 
target.getSource()), locations);
+        return InputLocation.of(-1, -1, InputSource.merge(source.getSource(), 
target.getSource()), locations);
     } // -- InputLocation merge( InputLocation, InputLocation, boolean )
 
     /**
@@ -183,7 +336,7 @@ public static InputLocation merge(InputLocation target, 
InputLocation source, Co
             }
         }
 
-        return new InputLocation(-1, -1, InputSource.merge(source.getSource(), 
target.getSource()), locations);
+        return InputLocation.of(-1, -1, InputSource.merge(source.getSource(), 
target.getSource()), locations);
     } // -- InputLocation merge( InputLocation, InputLocation, 
java.util.Collection )
 
     /**
diff --git 
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputSource.java 
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputSource.java
index f4d5e7fc67..09043542ad 100644
--- 
a/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputSource.java
+++ 
b/api/maven-api-model/src/main/java/org/apache/maven/api/model/InputSource.java
@@ -34,7 +34,7 @@
  *
  * @since 4.0.0
  */
-public class InputSource implements Serializable {
+public final class InputSource implements Serializable {
 
     private final String modelId;
     private final String location;
diff --git 
a/compat/maven-model/src/main/java/org/apache/maven/model/InputLocation.java 
b/compat/maven-model/src/main/java/org/apache/maven/model/InputLocation.java
index 70ef9bb688..0fe1e5dc1c 100644
--- a/compat/maven-model/src/main/java/org/apache/maven/model/InputLocation.java
+++ b/compat/maven-model/src/main/java/org/apache/maven/model/InputLocation.java
@@ -334,17 +334,17 @@ public void setLocations(java.util.Map<Object, 
InputLocation> locations) {
     public org.apache.maven.api.model.InputLocation toApiLocation() {
         if (locations != null && locations.values().contains(this)) {
             if (locations.size() == 1 && locations.values().iterator().next() 
== this) {
-                return new org.apache.maven.api.model.InputLocation(
+                return org.apache.maven.api.model.InputLocation.of(
                         lineNumber,
                         columnNumber,
                         source != null ? source.toApiSource() : null,
                         locations.keySet().iterator().next());
             } else {
-                return new org.apache.maven.api.model.InputLocation(
+                return org.apache.maven.api.model.InputLocation.of(
                         lineNumber, columnNumber, source != null ? 
source.toApiSource() : null);
             }
         } else {
-            return new org.apache.maven.api.model.InputLocation(
+            return org.apache.maven.api.model.InputLocation.of(
                     lineNumber,
                     columnNumber,
                     source != null ? source.toApiSource() : null,
diff --git 
a/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java 
b/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java
index 8a5d1e81a2..04266d4890 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/SettingsUtilsV4.java
@@ -377,7 +377,7 @@ private static org.apache.maven.api.model.InputLocation 
toLocation(
             org.apache.maven.api.settings.InputSource source = 
location.getSource();
             Map<Object, InputLocation> locs = 
location.getLocations().entrySet().stream()
                     .collect(Collectors.toMap(Map.Entry::getKey, e -> 
toLocation(e.getValue())));
-            return new org.apache.maven.api.model.InputLocation(
+            return org.apache.maven.api.model.InputLocation.of(
                     location.getLineNumber(),
                     location.getColumnNumber(),
                     source != null ? new 
org.apache.maven.api.model.InputSource("", source.getLocation()) : null,
diff --git a/src/mdo/java/InputLocation.java b/src/mdo/java/InputLocation.java
index 3345a1d1d0..3d9e4f7c39 100644
--- a/src/mdo/java/InputLocation.java
+++ b/src/mdo/java/InputLocation.java
@@ -25,14 +25,32 @@
 import java.util.Map;
 
 /**
- * Class InputLocation.
+ * Represents the location of an element within a model source file.
+ * <p>
+ * This class tracks the line and column numbers of elements in source files 
like POM files.
+ * It's used for error reporting and debugging to help identify where specific 
model elements
+ * are defined in the source files.
+ * <p>
+ * Note: Starting with Maven 4.0.0, it is recommended to use the static 
factory methods
+ * {@code of(...)} instead of constructors. The constructors are deprecated 
and will be
+ * removed in a future version.
+ *
+ * @since 4.0.0
  */
-public class InputLocation implements Serializable, InputLocationTracker {
+public final class InputLocation implements Serializable, InputLocationTracker 
{
     private final int lineNumber;
     private final int columnNumber;
     private final InputSource source;
     private final Map<Object, InputLocation> locations;
 
+    /**
+     * Creates an InputLocation with only a source, no line/column information.
+     * The line and column numbers will be set to -1 (unknown).
+     *
+     * @param source the input source where this location originates from
+     * @deprecated since 4.0.0-rc-6, use {@link #of(InputSource)} instead
+     */
+    @Deprecated
     public InputLocation(InputSource source) {
         this.lineNumber = -1;
         this.columnNumber = -1;
@@ -40,14 +58,41 @@ public InputLocation(InputSource source) {
         this.locations = Collections.singletonMap(0, this);
     }
 
+    /**
+     * Creates an InputLocation with line and column numbers but no source.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @deprecated since 4.0.0-rc-6, use {@link #of(int, int)} instead
+     */
+    @Deprecated
     public InputLocation(int lineNumber, int columnNumber) {
         this(lineNumber, columnNumber, null, null);
     }
 
+    /**
+     * Creates an InputLocation with line number, column number, and source.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @deprecated since 4.0.0-rc-6, use {@link #of(int, int, InputSource)} 
instead
+     */
+    @Deprecated
     public InputLocation(int lineNumber, int columnNumber, InputSource source) 
{
         this(lineNumber, columnNumber, source, null);
     }
 
+    /**
+     * Creates an InputLocation with line number, column number, source, and a 
self-location key.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @param selfLocationKey the key to map this location to itself in the 
locations map
+     * @deprecated since 4.0.0-rc-6, use {@link #of(int, int, InputSource, 
Object)} instead
+     */
+    @Deprecated
     public InputLocation(int lineNumber, int columnNumber, InputSource source, 
Object selfLocationKey) {
         this.lineNumber = lineNumber;
         this.columnNumber = columnNumber;
@@ -56,6 +101,16 @@ public InputLocation(int lineNumber, int columnNumber, 
InputSource source, Objec
                 selfLocationKey != null ? 
Collections.singletonMap(selfLocationKey, this) : Collections.emptyMap();
     }
 
+    /**
+     * Creates an InputLocation with line number, column number, source, and a 
complete locations map.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @param locations a map of keys to InputLocation instances for nested 
elements
+     * @deprecated since 4.0.0-rc-6, use {@link #of(int, int, InputSource, 
Map)} instead
+     */
+    @Deprecated
     public InputLocation(int lineNumber, int columnNumber, InputSource source, 
Map<Object, InputLocation> locations) {
         this.lineNumber = lineNumber;
         this.columnNumber = columnNumber;
@@ -63,23 +118,119 @@ public InputLocation(int lineNumber, int columnNumber, 
InputSource source, Map<O
         this.locations = ImmutableCollections.copy(locations);
     }
 
+    /**
+     * Creates an InputLocation with the specified source.
+     *
+     * @param source the input source
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(InputSource source) {
+        return new InputLocation(source);
+    }
+
+    /**
+     * Creates an InputLocation with the specified line and column numbers.
+     * The source and locations map will be null.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(int lineNumber, int columnNumber) {
+        return new InputLocation(lineNumber, columnNumber);
+    }
+
+    /**
+     * Creates an InputLocation with the specified line number, column number, 
and source.
+     * The locations map will be empty.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(int lineNumber, int columnNumber, 
InputSource source) {
+        return new InputLocation(lineNumber, columnNumber, source);
+    }
+
+    /**
+     * Creates an InputLocation with the specified line number, column number, 
source,
+     * and a self-location key. The locations map will contain a single entry 
mapping
+     * the selfLocationKey to this location.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @param selfLocationKey the key to map this location to itself in the 
locations map
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(int lineNumber, int columnNumber, 
InputSource source, Object selfLocationKey) {
+        return new InputLocation(lineNumber, columnNumber, source, 
selfLocationKey);
+    }
+
+    /**
+     * Creates an InputLocation with the specified line number, column number, 
source,
+     * and a complete locations map. This is typically used when merging or 
combining
+     * location information from multiple sources.
+     *
+     * @param lineNumber the line number in the source file (1-based)
+     * @param columnNumber the column number in the source file (1-based)
+     * @param source the input source where this location originates from
+     * @param locations a map of keys to InputLocation instances for nested 
elements
+     * @return a new InputLocation instance
+     * @since 4.0.0
+     */
+    public static InputLocation of(int lineNumber, int columnNumber, 
InputSource source, Map<Object, InputLocation> locations) {
+        return new InputLocation(lineNumber, columnNumber, source, locations);
+    }
+
+    /**
+     * Gets the one-based line number where this element is located in the 
source file.
+     *
+     * @return the line number, or -1 if unknown
+     */
     public int getLineNumber() {
         return lineNumber;
     }
 
+    /**
+     * Gets the one-based column number where this element is located in the 
source file.
+     *
+     * @return the column number, or -1 if unknown
+     */
     public int getColumnNumber() {
         return columnNumber;
     }
 
+    /**
+     * Gets the input source where this location originates from.
+     *
+     * @return the input source, or null if unknown
+     */
     public InputSource getSource() {
         return source;
     }
 
+    /**
+     * Gets the InputLocation for a specific nested element key.
+     *
+     * @param key the key to look up
+     * @return the InputLocation for the specified key, or null if not found
+     */
     @Override
     public InputLocation getLocation(Object key) {
         return locations != null ? locations.get(key) : null;
     }
 
+    /**
+     * Gets the map of nested element locations within this location.
+     *
+     * @return an immutable map of keys to InputLocation instances for nested 
elements
+     */
     public Map<Object, InputLocation> getLocations() {
         return locations;
     }
@@ -112,7 +263,7 @@ public static InputLocation merge(InputLocation target, 
InputLocation source, bo
             locations.putAll(sourceDominant ? sourceLocations : 
targetLocations);
         }
 
-        return new InputLocation(target.getLineNumber(), 
target.getColumnNumber(), target.getSource(), locations);
+        return InputLocation.of(target.getLineNumber(), 
target.getColumnNumber(), target.getSource(), locations);
     } // -- InputLocation merge( InputLocation, InputLocation, boolean )
 
     /**
@@ -151,7 +302,7 @@ public static InputLocation merge(InputLocation target, 
InputLocation source, Co
             }
         }
 
-        return new InputLocation(target.getLineNumber(), 
target.getColumnNumber(), target.getSource(), locations);
+        return InputLocation.of(target.getLineNumber(), 
target.getColumnNumber(), target.getSource(), locations);
     } // -- InputLocation merge( InputLocation, InputLocation, 
java.util.Collection )
 
     /**
diff --git a/src/mdo/java/InputSource.java b/src/mdo/java/InputSource.java
index aeb405f976..466e41fe2e 100644
--- a/src/mdo/java/InputSource.java
+++ b/src/mdo/java/InputSource.java
@@ -23,7 +23,7 @@
 /**
  * Class InputSource.
  */
-public class InputSource implements Serializable {
+public final class InputSource implements Serializable {
 
     private final String location;
 

Reply via email to