1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.impl.model.profile;
20
21 import java.util.HashMap;
22 import java.util.Map;
23 import java.util.function.UnaryOperator;
24
25 import org.apache.maven.api.di.Inject;
26 import org.apache.maven.api.di.Named;
27 import org.apache.maven.api.di.Singleton;
28 import org.apache.maven.api.model.Activation;
29 import org.apache.maven.api.model.Profile;
30 import org.apache.maven.api.services.BuilderProblem.Severity;
31 import org.apache.maven.api.services.Interpolator;
32 import org.apache.maven.api.services.ModelProblem.Version;
33 import org.apache.maven.api.services.ModelProblemCollector;
34 import org.apache.maven.api.services.VersionParser;
35 import org.apache.maven.api.services.model.ProfileActivationContext;
36 import org.apache.maven.api.services.model.ProfileActivator;
37
38 import static org.apache.maven.impl.model.profile.ConditionParser.toBoolean;
39
40
41
42
43
44 @Named("condition")
45 @Singleton
46 public class ConditionProfileActivator implements ProfileActivator {
47
48 private final VersionParser versionParser;
49
50 private final Interpolator interpolator;
51
52
53
54
55
56
57
58 @Inject
59 public ConditionProfileActivator(VersionParser versionParser, Interpolator interpolator) {
60 this.versionParser = versionParser;
61 this.interpolator = interpolator;
62 }
63
64
65
66
67
68
69
70
71
72 @Override
73 public boolean isActive(Profile profile, ProfileActivationContext context, ModelProblemCollector problems) {
74 if (profile.getActivation() == null || profile.getActivation().getCondition() == null) {
75 return false;
76 }
77 String condition = profile.getActivation().getCondition();
78 try {
79 Map<String, ConditionParser.ExpressionFunction> functions = registerFunctions(context, versionParser);
80 UnaryOperator<String> propertyResolver = s -> property(context, s);
81 return toBoolean(new ConditionParser(functions, propertyResolver).parse(condition));
82 } catch (Exception e) {
83 problems.add(
84 Severity.ERROR, Version.V41, "Error parsing profile activation condition: " + e.getMessage(), e);
85 return false;
86 }
87 }
88
89
90
91
92
93
94
95
96
97 @Override
98 public boolean presentInConfig(Profile profile, ProfileActivationContext context, ModelProblemCollector problems) {
99 Activation activation = profile.getActivation();
100 if (activation == null) {
101 return false;
102 }
103 return activation.getCondition() != null && !activation.getCondition().isBlank();
104 }
105
106
107
108
109
110
111
112
113 public Map<String, ConditionParser.ExpressionFunction> registerFunctions(
114 ProfileActivationContext context, VersionParser versionParser) {
115 Map<String, ConditionParser.ExpressionFunction> functions = new HashMap<>();
116
117 ConditionFunctions conditionFunctions = new ConditionFunctions(context, versionParser);
118
119 for (java.lang.reflect.Method method : ConditionFunctions.class.getDeclaredMethods()) {
120 String methodName = method.getName();
121 if (methodName.endsWith("_")) {
122 methodName = methodName.substring(0, methodName.length() - 1);
123 }
124 final String finalMethodName = methodName;
125
126 functions.put(finalMethodName, args -> {
127 try {
128 return method.invoke(conditionFunctions, args);
129 } catch (Exception e) {
130 StringBuilder causeChain = new StringBuilder();
131 Throwable cause = e;
132 while (cause != null) {
133 if (!causeChain.isEmpty()) {
134 causeChain.append(" Caused by: ");
135 }
136 causeChain.append(cause.toString());
137 cause = cause.getCause();
138 }
139 throw new RuntimeException(
140 "Error invoking function '" + finalMethodName + "': " + e + ". Cause chain: " + causeChain,
141 e);
142 }
143 });
144 }
145
146 return functions;
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 String property(ProfileActivationContext context, String name) {
164 String value = doGetProperty(context, name);
165 return interpolator.interpolate(value, s -> doGetProperty(context, s));
166 }
167
168 static String doGetProperty(ProfileActivationContext context, String name) {
169
170 if ("project.basedir".equals(name)) {
171 return context.getModelBaseDirectory();
172 }
173 if ("project.rootDirectory".equals(name)) {
174 return context.getModelRootDirectory();
175 }
176 if ("project.artifactId".equals(name)) {
177 return context.getModelArtifactId();
178 }
179 if ("project.packaging".equals(name)) {
180 return context.getModelPackaging();
181 }
182
183
184 String v = context.getUserProperty(name);
185 if (v == null) {
186
187
188
189 v = context.getModelProperty(name);
190 }
191 if (v == null) {
192
193 v = context.getSystemProperty(name);
194 }
195 return v;
196 }
197 }