[MNG-7895] Support ${project.basedir} in file profile activation
diff --git a/api/maven-api-model/src/main/mdo/maven.mdo b/api/maven-api-model/src/main/mdo/maven.mdo
index b7b37b4..2c24e74 100644
--- a/api/maven-api-model/src/main/mdo/maven.mdo
+++ b/api/maven-api-model/src/main/mdo/maven.mdo
@@ -3007,7 +3007,7 @@
         is the location of a file that needs to exist, and if it doesn't, the profile will be
         activated. On the other hand, {@code exists} will test for the existence of the file and if it is
         there, the profile will be activated.<br>
-        Variable interpolation for these file specifications is limited to {@code ${basedir}},
+        Variable interpolation for these file specifications is limited to {@code ${project.basedir}},
         system properties and user properties.]]></description>
       <fields>
         <field>
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java
index 7c420a3..1ab4e47 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java
@@ -69,11 +69,7 @@
             interpolator.addValueSource(new AbstractValueSource(false) {
                 @Override
                 public Object getValue(String expression) {
-                    /*
-                     * We intentionally only support ${basedir} and not ${project.basedir} as the latter form
-                     * would suggest that other project.* expressions can be used which is beyond the design.
-                     */
-                    if ("basedir".equals(expression)) {
+                    if ("basedir".equals(expression) || "project.basedir".equals(expression)) {
                         return basedir.getAbsolutePath();
                     }
                     return null;
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java b/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java
index 0ce909b..f7c7dc9 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java
@@ -37,11 +37,8 @@
 
 /**
  * Determines profile activation based on the existence/absence of some file.
- * File name interpolation support is limited to <code>${basedir}</code> (since Maven 3,
- * see <a href="https://issues.apache.org/jira/browse/MNG-2363">MNG-2363</a>),
+ * File name interpolation support is limited to <code>${project.basedir}</code>
  * system properties and user properties.
- * <code>${project.basedir}</code> is intentionally not supported as this form would suggest that other
- * <code>${project.*}</code> expressions can be used, which is however beyond the design.
  *
  * @see ActivationFile
  * @see org.apache.maven.model.validation.DefaultModelValidator#validateRawModel
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
index 83e22de..98aa018 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
@@ -68,6 +68,7 @@
 public class DefaultModelValidator implements ModelValidator {
 
     private static final Pattern EXPRESSION_NAME_PATTERN = Pattern.compile("\\$\\{(.+?)}");
+    private static final Pattern EXPRESSION_PROJECT_NAME_PATTERN = Pattern.compile("\\$\\{(project.+?)}");
 
     private static final String ILLEGAL_FS_CHARS = "\\/:\"<>|?*";
 
@@ -210,8 +211,7 @@
                             profile);
                 }
 
-                validate30RawProfileActivation(
-                        problems, profile.getActivation(), profile.getId(), prefix, "activation", request);
+                validate30RawProfileActivation(problems, profile.getActivation(), prefix);
 
                 validate20RawDependencies(
                         problems, profile.getDependencies(), prefix, "dependencies.dependency.", request);
@@ -283,54 +283,41 @@
         }
     }
 
-    private void validate30RawProfileActivation(
-            ModelProblemCollector problems,
-            Activation activation,
-            String sourceHint,
-            String prefix,
-            String fieldName,
-            ModelBuildingRequest request) {
-        if (activation == null) {
+    private void validate30RawProfileActivation(ModelProblemCollector problems, Activation activation, String prefix) {
+        if (activation == null || activation.getFile() == null) {
             return;
         }
 
         ActivationFile file = activation.getFile();
 
-        if (file != null) {
-            String path;
-            boolean missing;
+        String path;
+        String location;
 
-            if (file.getExists() != null && !file.getExists().isEmpty()) {
-                path = file.getExists();
-                missing = false;
-            } else if (file.getMissing() != null && !file.getMissing().isEmpty()) {
-                path = file.getMissing();
-                missing = true;
-            } else {
-                return;
-            }
+        if (file.getExists() != null && !file.getExists().isEmpty()) {
+            path = file.getExists();
+            location = "exists";
+        } else if (file.getMissing() != null && !file.getMissing().isEmpty()) {
+            path = file.getMissing();
+            location = "missing";
+        } else {
+            return;
+        }
 
-            if (path.contains("${project.basedir}")) {
-                addViolation(
-                        problems,
-                        Severity.WARNING,
-                        Version.V30,
-                        prefix + fieldName + (missing ? ".file.missing" : ".file.exists"),
-                        null,
-                        "Failed to interpolate file location " + path + " for profile " + sourceHint
-                                + ": ${project.basedir} expression not supported during profile activation, "
-                                + "use ${basedir} instead",
-                        file.getLocation(missing ? "missing" : "exists"));
-            } else if (hasProjectExpression(path)) {
-                addViolation(
-                        problems,
-                        Severity.WARNING,
-                        Version.V30,
-                        prefix + fieldName + (missing ? ".file.missing" : ".file.exists"),
-                        null,
-                        "Failed to interpolate file location " + path + " for profile " + sourceHint
-                                + ": ${project.*} expressions are not supported during profile activation",
-                        file.getLocation(missing ? "missing" : "exists"));
+        if (hasProjectExpression(path)) {
+            Matcher matcher = EXPRESSION_PROJECT_NAME_PATTERN.matcher(path);
+            while (matcher.find()) {
+                String propertyName = matcher.group(0);
+                if (!"${project.basedir}".equals(propertyName)) {
+                    addViolation(
+                            problems,
+                            Severity.WARNING,
+                            Version.V30,
+                            prefix + "activation.file." + location,
+                            null,
+                            "Failed to interpolate file location " + path + ": " + propertyName
+                                    + " expressions are not supported during profile activation.",
+                            file.getLocation(location));
+                }
             }
         }
     }
diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
index 79973d4..1148be9 100644
--- a/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
+++ b/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
@@ -814,4 +814,28 @@
         SimpleProblemCollector result = validateRaw("raw-model/repository-with-basedir-expression.xml");
         assertViolations(result, 0, 0, 0);
     }
+
+    @Test
+    void profileActivationWithAllowedExpression() throws Exception {
+        SimpleProblemCollector result = validateRaw("raw-model/profile-activation-file-with-allowed-expressions.xml");
+        assertViolations(result, 0, 0, 0);
+    }
+
+    @Test
+    void profileActivationWithProjectExpression() throws Exception {
+        SimpleProblemCollector result = validateRaw("raw-model/profile-activation-file-with-project-expressions.xml");
+        assertViolations(result, 0, 0, 2);
+
+        assertEquals(
+                "'profiles.profile[exists-project-version].activation.file.exists' "
+                        + "Failed to interpolate file location ${project.version}/test.txt: "
+                        + "${project.version} expressions are not supported during profile activation.",
+                result.getWarnings().get(0));
+
+        assertEquals(
+                "'profiles.profile[missing-project-version].activation.file.missing' "
+                        + "Failed to interpolate file location ${project.version}/test.txt: "
+                        + "${project.version} expressions are not supported during profile activation.",
+                result.getWarnings().get(1));
+    }
 }
diff --git a/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-allowed-expressions.xml b/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-allowed-expressions.xml
new file mode 100644
index 0000000..a4beb62
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-allowed-expressions.xml
@@ -0,0 +1,64 @@
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>aid</artifactId>
+  <groupId>gid</groupId>
+  <version>0.1</version>
+  <packaging>pom</packaging>
+
+  <profiles>
+    <profile>
+      <id>exists-basedir</id>
+      <activation>
+        <file>
+          <exists>${basedir}/test.txt</exists>
+        </file>
+      </activation>
+    </profile>
+    <profile>
+      <id>missing-basedir</id>
+      <activation>
+        <file>
+          <missing>${basedir}/test.txt</missing>
+        </file>
+      </activation>
+    </profile>
+
+    <profile>
+      <id>exists-project-basedir</id>
+      <activation>
+        <file>
+          <exists>${project.basedir}/test.txt</exists>
+        </file>
+      </activation>
+    </profile>
+    <profile>
+      <id>missing-project-basedir</id>
+      <activation>
+        <file>
+          <missing>${project.basedir}/test.txt</missing>
+        </file>
+      </activation>
+    </profile>
+
+  </profiles>
+</project>
diff --git a/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-project-expressions.xml b/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-project-expressions.xml
new file mode 100644
index 0000000..65953c3
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/validation/raw-model/profile-activation-file-with-project-expressions.xml
@@ -0,0 +1,48 @@
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>aid</artifactId>
+  <groupId>gid</groupId>
+  <version>0.1</version>
+  <packaging>pom</packaging>
+
+  <profiles>
+
+    <profile>
+      <id>exists-project-version</id>
+      <activation>
+        <file>
+          <exists>${project.version}/test.txt</exists>
+        </file>
+      </activation>
+    </profile>
+    <profile>
+      <id>missing-project-version</id>
+      <activation>
+        <file>
+          <missing>${project.version}/test.txt</missing>
+        </file>
+      </activation>
+    </profile>
+
+  </profiles>
+</project>