Skip to content

Commit 2efe3d2

Browse files
committed
Add combined expression evaluator to file activation property
1 parent 2e6fe1b commit 2efe3d2

File tree

9 files changed

+421
-20
lines changed

9 files changed

+421
-20
lines changed

maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.apache.maven.model.Model;
2323
import org.apache.maven.model.composition.DefaultDependencyManagementImporter;
2424
import org.apache.maven.model.composition.DependencyManagementImporter;
25+
import org.apache.maven.model.condition.CombinedValueEvaluator;
26+
import org.apache.maven.model.condition.DefaultCombinedValueEvaluator;
2527
import org.apache.maven.model.inheritance.DefaultInheritanceAssembler;
2628
import org.apache.maven.model.inheritance.InheritanceAssembler;
2729
import org.apache.maven.model.interpolation.ModelInterpolator;
@@ -111,7 +113,9 @@ protected ProfileActivator[] newProfileActivators()
111113
return new ProfileActivator[]
112114
{
113115
new JdkVersionProfileActivator(), new OperatingSystemProfileActivator(),
114-
new PropertyProfileActivator(), new FileProfileActivator().setPathTranslator( newPathTranslator() )
116+
new PropertyProfileActivator(),
117+
new FileProfileActivator().setPathTranslator( newPathTranslator() )
118+
.setCombinedValueEvaluator( newCombinedValueEvaluator() )
115119
};
116120
}
117121

@@ -125,6 +129,11 @@ protected PathTranslator newPathTranslator()
125129
return new DefaultPathTranslator();
126130
}
127131

132+
protected CombinedValueEvaluator newCombinedValueEvaluator()
133+
{
134+
return new DefaultCombinedValueEvaluator();
135+
}
136+
128137
protected ModelInterpolator newModelInterpolator()
129138
{
130139
UrlNormalizer normalizer = newUrlNormalizer();
@@ -237,7 +246,9 @@ private static class StubLifecycleBindingsInjector
237246
{
238247

239248
@Override
240-
public void injectLifecycleBindings( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
249+
public void injectLifecycleBindings( Model model,
250+
ModelBuildingRequest request,
251+
ModelProblemCollector problems )
241252
{
242253
}
243254

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.apache.maven.model.condition;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
/**
23+
* @author Loïc B.
24+
*/
25+
public interface CombinedValueEvaluator
26+
{
27+
28+
/**
29+
* Parses a string representing a condition, and evaluates its result using simple boolean logic.
30+
*
31+
* @param expression Boolean expression to be evaluated. Format : <br/>
32+
* all(condition1,condition2,...) or and(condition1,condition2,...) : will be true if all conditions are
33+
* true<br/>
34+
* any(condition1,condition2,...) or or(condition1,condition2,...) : will be true if at least one of the
35+
* conditions is true Nested operators are not supported.<br/>
36+
* If there is no condition expressed, the string is simply passed to the evaluator as-is.
37+
* @param evaluator Actual evaluator for a single condition. Will be called once for each condition found in the
38+
* expression
39+
* @return result of evaluation, depending on expression contents
40+
*/
41+
boolean evaluate( String expression, SingleValueEvaluator evaluator );
42+
43+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.apache.maven.model.condition;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
import java.util.regex.Matcher;
23+
import java.util.regex.Pattern;
24+
25+
import org.codehaus.plexus.component.annotations.Component;
26+
27+
/**
28+
* @author Loïc B.
29+
*/
30+
@Component( role = CombinedValueEvaluator.class )
31+
public class DefaultCombinedValueEvaluator
32+
implements CombinedValueEvaluator
33+
{
34+
private static final Pattern PATTERN_AND = Pattern.compile( "^(?:all|and)\\((?:([^,]*),)*([^,]*)\\)$" );
35+
36+
private static final Pattern PATTERN_OR = Pattern.compile( "^(?:any|or)\\((?:([^,]*),)*([^,]*)\\)$" );
37+
38+
/*
39+
* (non-Javadoc)
40+
* @see org.apache.maven.model.profile.activation.CombinedValueEvaluator#evaluate(java.lang.String,
41+
* org.apache.maven.model.profile.activation.SingleValueEvaluator)
42+
*/
43+
@Override
44+
public boolean evaluate( String expression, SingleValueEvaluator evaluator )
45+
{
46+
Matcher andMatcher = PATTERN_AND.matcher( expression );
47+
if ( andMatcher.matches() )
48+
{
49+
boolean result = true;
50+
for ( int i = 1; i <= andMatcher.groupCount(); i++ )
51+
{
52+
result &= evaluator.evaluate( andMatcher.group( i ) );
53+
}
54+
return result;
55+
}
56+
Matcher orMatcher = PATTERN_OR.matcher( expression );
57+
if ( orMatcher.matches() )
58+
{
59+
boolean result = false;
60+
for ( int i = 1; i <= andMatcher.groupCount(); i++ )
61+
{
62+
result |= evaluator.evaluate( orMatcher.group( i ) );
63+
}
64+
return result;
65+
}
66+
// Default
67+
return evaluator.evaluate( expression );
68+
}
69+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.apache.maven.model.condition;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
/**
23+
* @author Loïc B.
24+
*/
25+
public interface SingleValueEvaluator
26+
{
27+
/**
28+
* Evaluiates the expression and returns a boolean result. Expression evaluation and intended result is
29+
* implementation-dependent.
30+
*/
31+
boolean evaluate( String expression );
32+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.apache.maven.model.profile.activation;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
import java.io.File;
23+
24+
import org.apache.maven.model.condition.SingleValueEvaluator;
25+
import org.apache.maven.model.path.PathTranslator;
26+
27+
/**
28+
* @author Loïc B.
29+
*/
30+
public class FileExistenceEvaluator
31+
implements SingleValueEvaluator
32+
{
33+
34+
private final boolean missing;
35+
36+
private final PathTranslator pathTranslator;
37+
38+
private final File basedir;
39+
40+
/**
41+
* Creates the FileExistenceEvaluator for missing or existing files.
42+
*
43+
* @param missing true if the file should be missing, false if it should be existing
44+
* @param pathTranslator path translator implementation to be used
45+
*/
46+
public FileExistenceEvaluator( boolean missing, PathTranslator pathTranslator, File basedir )
47+
{
48+
this.missing = missing;
49+
this.pathTranslator = pathTranslator;
50+
this.basedir = basedir;
51+
}
52+
53+
/* (non-Javadoc)
54+
* @see org.apache.maven.model.profile.activation.SingleValueEvaluator#evaluate(java.lang.String)
55+
*/
56+
@Override
57+
public boolean evaluate( String path )
58+
{
59+
boolean reversed = false;
60+
if ( path.startsWith( "!" ) )
61+
{
62+
reversed = true;
63+
path = path.substring( 1 );
64+
}
65+
path = pathTranslator.alignToBaseDirectory( path, basedir );
66+
File f = new File( path );
67+
68+
if ( !f.isAbsolute() )
69+
{
70+
return false;
71+
}
72+
73+
boolean fileExists = f.exists();
74+
75+
return missing ^ reversed ? !fileExists : fileExists;
76+
}
77+
78+
}

maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@
2424
import org.apache.maven.model.Activation;
2525
import org.apache.maven.model.ActivationFile;
2626
import org.apache.maven.model.Profile;
27-
import org.apache.maven.model.building.ModelProblemCollector;
2827
import org.apache.maven.model.building.ModelProblem.Severity;
2928
import org.apache.maven.model.building.ModelProblem.Version;
29+
import org.apache.maven.model.building.ModelProblemCollector;
3030
import org.apache.maven.model.building.ModelProblemCollectorRequest;
31+
import org.apache.maven.model.condition.CombinedValueEvaluator;
3132
import org.apache.maven.model.path.PathTranslator;
3233
import org.apache.maven.model.profile.ProfileActivationContext;
3334
import org.codehaus.plexus.component.annotations.Component;
@@ -53,16 +54,24 @@
5354
public class FileProfileActivator
5455
implements ProfileActivator
5556
{
56-
5757
@Requirement
5858
private PathTranslator pathTranslator;
5959

60+
@Requirement
61+
private CombinedValueEvaluator combinedValueEvaluator;
62+
6063
public FileProfileActivator setPathTranslator( PathTranslator pathTranslator )
6164
{
6265
this.pathTranslator = pathTranslator;
6366
return this;
6467
}
6568

69+
public FileProfileActivator setCombinedValueEvaluator( CombinedValueEvaluator combinedValueEvaluator )
70+
{
71+
this.combinedValueEvaluator = combinedValueEvaluator;
72+
return this;
73+
}
74+
6675
@Override
6776
public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
6877
{
@@ -146,9 +155,8 @@ else if ( path.contains( "${basedir}" ) )
146155
return false;
147156
}
148157

149-
path = pathTranslator.alignToBaseDirectory( path, basedir );
150-
151158
// replace activation value with interpolated value
159+
// (expression is still present & paths are still relative at this step)
152160
if ( missing )
153161
{
154162
file.setMissing( path );
@@ -158,16 +166,7 @@ else if ( path.contains( "${basedir}" ) )
158166
file.setExists( path );
159167
}
160168

161-
File f = new File( path );
162-
163-
if ( !f.isAbsolute() )
164-
{
165-
return false;
166-
}
167-
168-
boolean fileExists = f.exists();
169-
170-
return missing ? !fileExists : fileExists;
169+
return combinedValueEvaluator.evaluate( path, new FileExistenceEvaluator( missing, pathTranslator, basedir ) );
171170
}
172171

173172
@Override

0 commit comments

Comments
 (0)