diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java index a9ed4be3be..07dd224705 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java @@ -19,9 +19,11 @@ package org.apache.maven.plugin; import java.io.File; +import java.nio.file.Path; import java.util.Properties; import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.interpolation.reflection.ReflectionValueExtractor; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.project.MavenProject; @@ -174,7 +176,13 @@ public Object evaluate(String expr, Class type) throws ExpressionEvaluationEx if (pathSeparator > 0) { String pathExpression = expression.substring(0, pathSeparator); value = ReflectionValueExtractor.evaluate(pathExpression, session); - value = value + expression.substring(pathSeparator); + if (pathSeparator < expression.length() - 1) { + if (value instanceof Path) { + value = ((Path) value).resolve(expression.substring(pathSeparator + 1)); + } else { + value = value + expression.substring(pathSeparator); + } + } } else { value = ReflectionValueExtractor.evaluate(expression, session); } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java index 2357af54ef..530ed724ff 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java @@ -28,6 +28,7 @@ import org.apache.maven.api.Session; import org.apache.maven.internal.impl.DefaultMojoExecution; import org.apache.maven.internal.impl.DefaultSession; +import org.apache.maven.model.interpolation.reflection.ReflectionValueExtractor; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; @@ -177,7 +178,13 @@ public Object evaluate(String expr, Class type) throws ExpressionEvaluationEx if (pathSeparator > 0) { String pathExpression = expression.substring(0, pathSeparator); value = ReflectionValueExtractor.evaluate(pathExpression, session); - value = value + expression.substring(pathSeparator); + if (pathSeparator < expression.length() - 1) { + if (value instanceof Path) { + value = ((Path) value).resolve(expression.substring(pathSeparator + 1)); + } else { + value = value + expression.substring(pathSeparator); + } + } } else { value = ReflectionValueExtractor.evaluate(expression, session); } diff --git a/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java b/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java index 8bd464057f..582dfb739c 100644 --- a/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java +++ b/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java @@ -21,12 +21,14 @@ import javax.inject.Inject; import java.io.File; +import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Properties; import org.apache.maven.AbstractCoreMavenComponentTestCase; @@ -34,6 +36,7 @@ import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.bridge.MavenRepositorySystem; +import org.apache.maven.configuration.internal.EnhancedComponentConfigurator; import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; @@ -41,6 +44,8 @@ import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; +import org.apache.maven.model.building.DefaultModelBuildingRequest; +import org.apache.maven.model.interpolation.reflection.IntrospectionException; import org.apache.maven.model.root.RootLocator; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; @@ -50,6 +55,8 @@ import org.codehaus.plexus.MutablePlexusContainer; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; +import org.codehaus.plexus.configuration.DefaultPlexusConfiguration; +import org.codehaus.plexus.util.Os; import org.junit.jupiter.api.Test; import static org.codehaus.plexus.testing.PlexusExtension.getTestFile; @@ -386,6 +393,63 @@ void testRootDirectory() throws Exception { assertInstanceOf(Path.class, ee.evaluate("${session.rootDirectory}")); } + @Test + public void testUri() throws Exception { + Path path = Paths.get("").toAbsolutePath(); + + MavenSession mavenSession = createMavenSession(null); + mavenSession.getRequest().setTopDirectory(path); + mavenSession.getRequest().setRootDirectory(path); + + Object result = new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null) + .evaluate("${session.rootDirectory.uri}"); + assertEquals(path.toUri(), result); + } + + @Test + public void testPath() throws Exception { + Path path = Paths.get("").toAbsolutePath(); + + MavenSession mavenSession = createMavenSession(null); + mavenSession.getRequest().setTopDirectory(path); + mavenSession.getRequest().setRootDirectory(path); + + Object result = new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null) + .evaluate("${session.rootDirectory/target}"); + assertEquals(path.resolve("target"), result); + } + + @Test + public void testPluginInjection() throws Exception { + Path path = Paths.get("rép➜α").toAbsolutePath(); + + MavenSession mavenSession = createMavenSession(null); + mavenSession.getRequest().setTopDirectory(path); + mavenSession.getRequest().setRootDirectory(path); + DefaultModelBuildingRequest mbr = new DefaultModelBuildingRequest(); + + PluginParameterExpressionEvaluatorV4 evaluator = + new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null); + + DefaultPlexusConfiguration configuration = new DefaultPlexusConfiguration("config"); + configuration.addChild("uri", "${session.rootDirectory.uri}"); + configuration.addChild("path", "${session.rootDirectory}"); + configuration.addChild("uriString", "${session.rootDirectory.uri.string}"); + configuration.addChild("uriAsciiString", "${session.rootDirectory.uri.ASCIIString}"); + configuration.addChild("pathString", "${session.rootDirectory.string}"); + + PluginParameterExpressionEvaluatorV4Test.Mojo mojo = new PluginParameterExpressionEvaluatorV4Test.Mojo(); + new EnhancedComponentConfigurator().configureComponent(mojo, configuration, evaluator, null); + + assertEquals( + Objects.equals(path.toUri().toString(), path.toUri().toASCIIString()), !Os.isFamily(Os.FAMILY_WINDOWS)); + assertEquals(mojo.uri, path.toUri()); + assertEquals(mojo.path, path); + assertEquals(mojo.uriString, path.toUri().toString()); + assertEquals(mojo.uriAsciiString, path.toUri().toASCIIString()); + assertEquals(mojo.pathString, path.toString()); + } + private MavenProject createDefaultProject() { return new MavenProject(new Model()); } @@ -442,4 +506,12 @@ protected String getProjectsDirectory() { // TODO Auto-generated method stub return null; } + + public static class Mojo { + URI uri; + Path path; + String uriString; + String uriAsciiString; + String pathString; + } } diff --git a/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4Test.java b/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4Test.java index 8cb9964016..630119241a 100644 --- a/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4Test.java +++ b/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4Test.java @@ -21,12 +21,14 @@ import javax.inject.Inject; import java.io.File; +import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Properties; import org.apache.maven.AbstractCoreMavenComponentTestCase; @@ -35,6 +37,7 @@ import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.bridge.MavenRepositorySystem; +import org.apache.maven.configuration.internal.EnhancedComponentConfigurator; import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; @@ -44,6 +47,8 @@ import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; +import org.apache.maven.model.building.DefaultModelBuildingRequest; +import org.apache.maven.model.interpolation.reflection.IntrospectionException; import org.apache.maven.model.root.RootLocator; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; @@ -53,6 +58,8 @@ import org.codehaus.plexus.MutablePlexusContainer; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; +import org.codehaus.plexus.configuration.DefaultPlexusConfiguration; +import org.codehaus.plexus.util.Os; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.internal.impl.DefaultRepositorySystem; import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; @@ -458,9 +465,74 @@ private MavenSession newMavenSession() throws Exception { return createMavenSession(null); } + @Test + public void testUri() throws Exception { + Path path = Paths.get("").toAbsolutePath(); + + MavenSession mavenSession = createMavenSession(null); + mavenSession.getRequest().setTopDirectory(path); + mavenSession.getRequest().setRootDirectory(path); + + Object result = new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null) + .evaluate("${session.rootDirectory.uri}"); + assertEquals(path.toUri(), result); + } + + @Test + public void testPath() throws Exception { + Path path = Paths.get("").toAbsolutePath(); + + MavenSession mavenSession = createMavenSession(null); + mavenSession.getRequest().setTopDirectory(path); + mavenSession.getRequest().setRootDirectory(path); + + Object result = new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null) + .evaluate("${session.rootDirectory/target}"); + assertEquals(path.resolve("target"), result); + } + + @Test + public void testPluginInjection() throws Exception { + Path path = Paths.get("rép➜α").toAbsolutePath(); + + MavenSession mavenSession = createMavenSession(null); + mavenSession.getRequest().setTopDirectory(path); + mavenSession.getRequest().setRootDirectory(path); + DefaultModelBuildingRequest mbr = new DefaultModelBuildingRequest(); + + PluginParameterExpressionEvaluatorV4 evaluator = + new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null); + + DefaultPlexusConfiguration configuration = new DefaultPlexusConfiguration("config"); + configuration.addChild("uri", "${session.rootDirectory.uri}"); + configuration.addChild("path", "${session.rootDirectory}"); + configuration.addChild("uriString", "${session.rootDirectory.uri.string}"); + configuration.addChild("uriAsciiString", "${session.rootDirectory.uri.ASCIIString}"); + configuration.addChild("pathString", "${session.rootDirectory.string}"); + + Mojo mojo = new Mojo(); + new EnhancedComponentConfigurator().configureComponent(mojo, configuration, evaluator, null); + + assertEquals( + Objects.equals(path.toUri().toString(), path.toUri().toASCIIString()), !Os.isFamily(Os.FAMILY_WINDOWS)); + assertEquals(mojo.uri, path.toUri()); + assertEquals(mojo.path, path); + assertEquals(mojo.uriString, path.toUri().toString()); + assertEquals(mojo.uriAsciiString, path.toUri().toASCIIString()); + assertEquals(mojo.pathString, path.toString()); + } + @Override protected String getProjectsDirectory() { // TODO Auto-generated method stub return null; } + + public static class Mojo { + URI uri; + Path path; + String uriString; + String uriAsciiString; + String pathString; + } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java index 745506007f..97c8984c60 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java @@ -21,6 +21,7 @@ import javax.inject.Inject; import java.io.File; +import java.net.URI; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -39,9 +40,7 @@ import org.codehaus.plexus.interpolation.AbstractValueSource; import org.codehaus.plexus.interpolation.InterpolationPostProcessor; import org.codehaus.plexus.interpolation.MapBasedValueSource; -import org.codehaus.plexus.interpolation.ObjectBasedValueSource; import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor; -import org.codehaus.plexus.interpolation.PrefixedObjectValueSource; import org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper; import org.codehaus.plexus.interpolation.RecursionInterceptor; import org.codehaus.plexus.interpolation.ValueSource; @@ -140,7 +139,11 @@ protected List createValueSources( @Override public Object getValue(String expression) { if ("basedir".equals(expression)) { - return projectDir.getAbsolutePath(); + return projectDir.getAbsoluteFile().toPath().toString(); + } else if (expression.startsWith("basedir.")) { + Path basedir = projectDir.getAbsoluteFile().toPath(); + return new ObjectBasedValueSource(basedir) + .getValue(expression.substring("basedir.".length())); } return null; } @@ -159,6 +162,11 @@ public Object getValue(String expression) { .toPath() .toUri() .toASCIIString(); + } else if (expression.startsWith("baseUri.")) { + URI baseUri = + projectDir.getAbsoluteFile().toPath().toUri(); + return new ObjectBasedValueSource(baseUri) + .getValue(expression.substring("baseUri.".length())); } return null; } @@ -177,6 +185,11 @@ public Object getValue(String expression) { Path base = projectDir != null ? projectDir.toPath() : null; Path root = rootLocator.findMandatoryRoot(base); return root.toFile().getPath(); + } else if (expression.startsWith("rootDirectory.")) { + Path base = projectDir != null ? projectDir.toPath() : null; + Path root = rootLocator.findMandatoryRoot(base); + return new ObjectBasedValueSource(root) + .getValue(expression.substring("rootDirectory.".length())); } return null; } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ObjectBasedValueSource.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ObjectBasedValueSource.java new file mode 100644 index 0000000000..5a104b0c25 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ObjectBasedValueSource.java @@ -0,0 +1,84 @@ +/* + * 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. + */ +package org.apache.maven.model.interpolation; + +/* + * Copyright 2007 The Codehaus Foundation. + * + * Licensed 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. + */ + +import org.apache.maven.model.interpolation.reflection.ReflectionValueExtractor; +import org.codehaus.plexus.interpolation.AbstractValueSource; + +/** + * Wraps an object, providing reflective access to the object graph of which the + * supplied object is the root. Expressions like 'child.name' will translate into + * 'rootObject.getChild().getName()' for non-boolean properties, and + * 'rootObject.getChild().isName()' for boolean properties. + */ +public class ObjectBasedValueSource extends AbstractValueSource { + + private final Object root; + + /** + * Construct a new value source, using the supplied object as the root from + * which to start, and using expressions split at the dot ('.') to navigate + * the object graph beneath this root. + * @param root the root of the graph. + */ + public ObjectBasedValueSource(Object root) { + super(true); + this.root = root; + } + + /** + *

Split the expression into parts, tokenized on the dot ('.') character. Then, + * starting at the root object contained in this value source, apply each part + * to the object graph below this root, using either 'getXXX()' or 'isXXX()' + * accessor types to resolve the value for each successive expression part. + * Finally, return the result of the last expression part's resolution.

+ * + *

NOTE: The object-graph nagivation actually takes place via the + * {@link ReflectionValueExtractor} class.

+ */ + public Object getValue(String expression) { + if (expression == null || expression.trim().isEmpty()) { + return null; + } + + try { + return ReflectionValueExtractor.evaluate(expression, root, false); + } catch (Exception e) { + addFeedback("Failed to extract \'" + expression + "\' from: " + root, e); + } + + return null; + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PrefixedObjectValueSource.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PrefixedObjectValueSource.java new file mode 100644 index 0000000000..4a70115c25 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PrefixedObjectValueSource.java @@ -0,0 +1,62 @@ +/* + * 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. + */ +package org.apache.maven.model.interpolation; + +import java.util.List; + +import org.codehaus.plexus.interpolation.AbstractDelegatingValueSource; +import org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper; +import org.codehaus.plexus.interpolation.QueryEnabledValueSource; + +/** + * Wraps an arbitrary object with an {@link ObjectBasedValueSource} instance, then + * wraps that source with a {@link PrefixedValueSourceWrapper} instance, to which + * this class delegates all of its calls. + */ +public class PrefixedObjectValueSource extends AbstractDelegatingValueSource implements QueryEnabledValueSource { + + /** + * Wrap the specified root object, allowing the specified expression prefix. + * @param prefix the prefix. + * @param root the root of the graph. + */ + public PrefixedObjectValueSource(String prefix, Object root) { + super(new PrefixedValueSourceWrapper(new ObjectBasedValueSource(root), prefix)); + } + + /** + * Wrap the specified root object, allowing the specified list of expression + * prefixes and setting whether the {@link PrefixedValueSourceWrapper} allows + * unprefixed expressions. + * @param possiblePrefixes The possible prefixes. + * @param root The root of the graph. + * @param allowUnprefixedExpressions if we allow undefined expressions or not. + */ + public PrefixedObjectValueSource(List possiblePrefixes, Object root, boolean allowUnprefixedExpressions) { + super(new PrefixedValueSourceWrapper( + new ObjectBasedValueSource(root), possiblePrefixes, allowUnprefixedExpressions)); + } + + /** + * {@inheritDoc} + */ + public String getLastExpression() { + return ((QueryEnabledValueSource) getDelegate()).getLastExpression(); + } +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/ClassMap.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ClassMap.java similarity index 99% rename from maven-core/src/main/java/org/apache/maven/plugin/ClassMap.java rename to maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ClassMap.java index f71e6f5003..743875eda8 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/ClassMap.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ClassMap.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.plugin; +package org.apache.maven.model.interpolation.reflection; import java.lang.reflect.Method; import java.lang.reflect.Modifier; diff --git a/maven-core/src/main/java/org/apache/maven/plugin/IntrospectionException.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/IntrospectionException.java similarity index 90% rename from maven-core/src/main/java/org/apache/maven/plugin/IntrospectionException.java rename to maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/IntrospectionException.java index 38e2d83441..65e75fb61a 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/IntrospectionException.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/IntrospectionException.java @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.plugin; +package org.apache.maven.model.interpolation.reflection; -class IntrospectionException extends Exception { +public class IntrospectionException extends Exception { /** * diff --git a/maven-core/src/main/java/org/apache/maven/plugin/MethodMap.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/MethodMap.java similarity index 99% rename from maven-core/src/main/java/org/apache/maven/plugin/MethodMap.java rename to maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/MethodMap.java index d86e0800d4..1e7bc0ecab 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/MethodMap.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/MethodMap.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.plugin; +package org.apache.maven.model.interpolation.reflection; import java.lang.reflect.Method; import java.util.ArrayList; diff --git a/maven-core/src/main/java/org/apache/maven/plugin/ReflectionValueExtractor.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractor.java similarity index 93% rename from maven-core/src/main/java/org/apache/maven/plugin/ReflectionValueExtractor.java rename to maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractor.java index 64d5453661..e36094cbb6 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/ReflectionValueExtractor.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractor.java @@ -16,26 +16,30 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.plugin; +package org.apache.maven.model.interpolation.reflection; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.WeakHashMap; import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.annotations.Nullable; -import org.apache.maven.plugin.MethodMap.AmbiguousException; +import org.apache.maven.model.interpolation.reflection.MethodMap.AmbiguousException; /** * Using simple dotted expressions to extract the values from an Object instance using JSP-like expressions * such as {@code project.build.sourceDirectory}. + *

+ * In addition to usual getters using {@code getXxx} or {@code isXxx} suffixes, accessors + * using {@code asXxx} or {@code toXxx} prefixes are also supported. */ -class ReflectionValueExtractor { +public class ReflectionValueExtractor { private static final Object[] OBJECT_ARGS = new Object[0]; /** @@ -263,22 +267,14 @@ private static Object getPropertyValue(Object value, String property) throws Int ClassMap classMap = getClassMap(value.getClass()); String methodBase = Character.toTitleCase(property.charAt(0)) + property.substring(1); - String methodName = "get" + methodBase; try { - Method method = classMap.findMethod(methodName); - - if (method == null) { - // perhaps this is a boolean property?? - methodName = "is" + methodBase; - - method = classMap.findMethod(methodName); + for (String prefix : Arrays.asList("get", "is", "to", "as")) { + Method method = classMap.findMethod(prefix + methodBase); + if (method != null) { + return method.invoke(value, OBJECT_ARGS); + } } - - if (method == null) { - return null; - } - - return method.invoke(value, OBJECT_ARGS); + return null; } catch (InvocationTargetException e) { throw new IntrospectionException(e.getTargetException()); } catch (AmbiguousException | IllegalAccessException e) { diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java index dac2bf65f2..6d28832226 100644 --- a/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java +++ b/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java @@ -331,6 +331,30 @@ void testRootDirectory() throws Exception { assertEquals("file:myRootDirectory/temp-repo", (out.getRepositories().get(0)).getUrl()); } + @Test + void testRootDirectoryWithUri() throws Exception { + Path rootDirectory = Paths.get("myRootDirectory"); + + Model model = Model.newBuilder() + .version("3.8.1") + .artifactId("foo") + .repositories(Collections.singletonList(Repository.newBuilder() + .url("${project.rootDirectory.uri}/temp-repo") + .build())) + .build(); + + ModelInterpolator interpolator = createInterpolator(); + + final SimpleProblemCollector collector = new SimpleProblemCollector(); + Model out = interpolator.interpolateModel( + model, rootDirectory.toFile(), createModelBuildingRequest(context), collector); + assertProblemFree(collector); + + assertEquals( + rootDirectory.resolve("temp-repo").toUri().toString(), + (out.getRepositories().get(0)).getUrl()); + } + @Test void testRootDirectoryWithNull() throws Exception { Model model = Model.newBuilder() diff --git a/maven-core/src/test/java/org/apache/maven/plugin/ReflectionValueExtractorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractorTest.java similarity index 99% rename from maven-core/src/test/java/org/apache/maven/plugin/ReflectionValueExtractorTest.java rename to maven-model-builder/src/test/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractorTest.java index d39745a7e4..1c960c886d 100644 --- a/maven-core/src/test/java/org/apache/maven/plugin/ReflectionValueExtractorTest.java +++ b/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractorTest.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.plugin; +package org.apache.maven.model.interpolation.reflection; /* * Copyright The Codehaus Foundation.